From 135657206fba40c3f6138362b62457f4452e578b Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 16 Apr 2016 18:09:51 +0300 Subject: [PATCH 01/15] MIR: Do not require END_BLOCK to always exist MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Once upon a time, along with START_BLOCK and END_BLOCK in the castle of important blocks also lived a RESUME_BLOCK (or was it UNWIND_BLOCK? Either works, I don’t remember anymore). This trinity of important blocks were required to always exist from the birth to death of the MIR-land they belonged to. Some time later, it was discovered that RESUME_BLOCK was just a lazy goon enjoying comfortable life in the light of fame of the other two. Needless to say, once found out, the RESUME_BLOCK was quickly slain and disposed of. Now, the all-seeing eye of ours discovers that END_BLOCK is actually the more evil and better disguised twin of the slain RESUME_BLOCK. Thus END_BLOCK gets slain and quickly disposed of. Glory to the START_BLOCK, one and only lord of the important blocks’ castle! --- Basically, all this does, is removing restriction for END_BLOCK to exist past the first invocation of RemoveDeadBlocks pass. This way for functions whose CFG does not reach the `END_BLOCK` end up not containing the block. As far as the implementation goes, I’m not entirely satisfied with the `BasicBlock::end_block`, I had hoped to make `new` a `const fn` and then just have a `const END_BLOCK` private to mir::build, but it turns out that constant functions don’t yet support conditionals nor a way to assert. --- src/librustc/mir/repr.rs | 13 ++++++++----- src/librustc_mir/build/expr/into.rs | 2 +- src/librustc_mir/build/mod.rs | 10 +++++----- src/librustc_mir/lib.rs | 1 + src/librustc_mir/transform/remove_dead_blocks.rs | 3 +-- src/librustc_trans/mir/mod.rs | 2 -- 6 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index aacb3aae81c..67cd28c30e6 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -59,9 +59,6 @@ pub struct Mir<'tcx> { /// where execution begins pub const START_BLOCK: BasicBlock = BasicBlock(0); -/// where execution ends, on normal return -pub const END_BLOCK: BasicBlock = BasicBlock(1); - impl<'tcx> Mir<'tcx> { pub fn all_basic_blocks(&self) -> Vec { (0..self.basic_blocks.len()) @@ -216,6 +213,13 @@ impl BasicBlock { BasicBlock(index as u32) } + /// Returns a BasicBlock with index 1. This is actual end block (containing + /// the Return terminator) only during the building of MIR and should not be + /// used outside that. + pub const fn end_block() -> BasicBlock { + BasicBlock(1) + } + /// Extract the index. pub fn index(self) -> usize { self.0 as usize @@ -305,8 +309,7 @@ pub enum TerminatorKind<'tcx> { Resume, /// Indicates a normal return. The ReturnPointer lvalue should - /// have been filled in by now. This should only occur in the - /// `END_BLOCK`. + /// have been filled in by now. This should occur at most once. Return, /// Drop the Lvalue diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 231d7da10a0..976d13fca29 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -262,7 +262,7 @@ impl<'a,'tcx> Builder<'a,'tcx> { } }; let extent = this.extent_of_return_scope(); - this.exit_scope(expr_span, extent, block, END_BLOCK); + this.exit_scope(expr_span, extent, block, BasicBlock::end_block()); this.cfg.start_new_block().unit() } ExprKind::Call { ty, fun, args } => { diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 2e5b6a952b7..a92d686b85d 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -183,7 +183,8 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>, }; assert_eq!(builder.cfg.start_new_block(), START_BLOCK); - assert_eq!(builder.cfg.start_new_block(), END_BLOCK); + let end_block = builder.cfg.start_new_block(); + assert_eq!(end_block, BasicBlock::end_block()); let mut arg_decls = None; // assigned to `Some` in closures below @@ -205,11 +206,10 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>, })); builder.cfg.terminate(block, call_site_scope_id, span, - TerminatorKind::Goto { target: END_BLOCK }); - builder.cfg.terminate(END_BLOCK, call_site_scope_id, span, + TerminatorKind::Goto { target: end_block }); + builder.cfg.terminate(end_block, call_site_scope_id, span, TerminatorKind::Return); - - END_BLOCK.unit() + end_block.unit() }); assert!( diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index ced73f34e0d..78d3f4f6207 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -21,6 +21,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![unstable(feature = "rustc_private", issue = "27812")] #![feature(box_patterns)] +#![feature(const_fn)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(question_mark)] diff --git a/src/librustc_mir/transform/remove_dead_blocks.rs b/src/librustc_mir/transform/remove_dead_blocks.rs index dc1ddad124f..2099e9a435a 100644 --- a/src/librustc_mir/transform/remove_dead_blocks.rs +++ b/src/librustc_mir/transform/remove_dead_blocks.rs @@ -43,9 +43,8 @@ pub struct RemoveDeadBlocks; impl<'tcx> MirPass<'tcx> for RemoveDeadBlocks { fn run_pass(&mut self, _: &TyCtxt<'tcx>, _: NodeId, mir: &mut Mir<'tcx>) { let mut seen = BitVector::new(mir.basic_blocks.len()); - // These blocks are always required. + // This block is always required. seen.insert(START_BLOCK.index()); - seen.insert(END_BLOCK.index()); let mut worklist = Vec::with_capacity(4); worklist.push(START_BLOCK); diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs index 1869845ccb1..eb907f496eb 100644 --- a/src/librustc_trans/mir/mod.rs +++ b/src/librustc_trans/mir/mod.rs @@ -164,8 +164,6 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) { .map(|&bb|{ if bb == mir::START_BLOCK { fcx.new_block("start", None) - } else if bb == mir::END_BLOCK { - fcx.new_block("end", None) } else { fcx.new_block(&format!("{:?}", bb), None) } From 574450a413a093d3ab97f8636f1c8f65e76bf1fb Mon Sep 17 00:00:00 2001 From: mitaa Date: Mon, 18 Apr 2016 17:32:00 +0200 Subject: [PATCH 02/15] Fix the strip-hidden `ImplStripper` Instead of stripping impls which reference *stripped* items, we keep impls which reference *retained* items. We do this because when we strip an item we immediately return, and do not recurse into it - leaving the contained items non-stripped from the point of view of the `ImplStripper`. --- src/librustdoc/passes.rs | 63 ++++++++++++--------------------- src/test/rustdoc/issue-33069.rs | 20 +++++++++++ 2 files changed, 42 insertions(+), 41 deletions(-) create mode 100644 src/test/rustdoc/issue-33069.rs diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs index 0042afb1fd5..15bb0f7592b 100644 --- a/src/librustdoc/passes.rs +++ b/src/librustdoc/passes.rs @@ -24,19 +24,17 @@ use fold::FoldItem::Strip; /// Strip items marked `#[doc(hidden)]` pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult { - let mut stripped = DefIdSet(); + let mut retained = DefIdSet(); // strip all #[doc(hidden)] items let krate = { struct Stripper<'a> { - stripped: &'a mut DefIdSet + retained: &'a mut DefIdSet } impl<'a> fold::DocFolder for Stripper<'a> { fn fold_item(&mut self, i: Item) -> Option { if i.attrs.list("doc").has_word("hidden") { debug!("found one in strip_hidden; removing"); - self.stripped.insert(i.def_id); - // use a dedicated hidden item for given item type if any match i.inner { clean::StructFieldItem(..) | clean::ModuleItem(..) => { @@ -44,42 +42,19 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult { } _ => return None, } + } else { + self.retained.insert(i.def_id); } self.fold_item_recur(i) } } - let mut stripper = Stripper{ stripped: &mut stripped }; + let mut stripper = Stripper{ retained: &mut retained }; stripper.fold_crate(krate) }; - // strip any traits implemented on stripped items - { - struct ImplStripper<'a> { - stripped: &'a mut DefIdSet - } - impl<'a> fold::DocFolder for ImplStripper<'a> { - fn fold_item(&mut self, i: Item) -> Option { - if let clean::ImplItem(clean::Impl{ - for_: clean::ResolvedPath{ did, .. }, - ref trait_, .. - }) = i.inner { - // Impls for stripped types don't need to exist - if self.stripped.contains(&did) { - return None; - } - // Impls of stripped traits also don't need to exist - if let Some(did) = trait_.def_id() { - if self.stripped.contains(&did) { - return None; - } - } - } - self.fold_item_recur(i) - } - } - let mut stripper = ImplStripper{ stripped: &mut stripped }; - stripper.fold_crate(krate) - } + // strip all impls referencing stripped items + let mut stripper = ImplStripper { retained: &retained }; + stripper.fold_crate(krate) } /// Strip private items from the point of view of a crate or externally from a @@ -101,11 +76,9 @@ pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult { krate = ImportStripper.fold_crate(stripper.fold_crate(krate)); } - // strip all private implementations of traits - { - let mut stripper = ImplStripper(&retained); - stripper.fold_crate(krate) - } + // strip all impls referencing private items + let mut stripper = ImplStripper { retained: &retained }; + stripper.fold_crate(krate) } struct Stripper<'a> { @@ -204,13 +177,21 @@ impl<'a> fold::DocFolder for Stripper<'a> { } } -// This stripper discards all private impls of traits -struct ImplStripper<'a>(&'a DefIdSet); +// This stripper discards all impls which reference stripped items +struct ImplStripper<'a> { + retained: &'a DefIdSet +} + impl<'a> fold::DocFolder for ImplStripper<'a> { fn fold_item(&mut self, i: Item) -> Option { if let clean::ImplItem(ref imp) = i.inner { + if let Some(did) = imp.for_.def_id() { + if did.is_local() && !self.retained.contains(&did) { + return None; + } + } if let Some(did) = imp.trait_.def_id() { - if did.is_local() && !self.0.contains(&did) { + if did.is_local() && !self.retained.contains(&did) { return None; } } diff --git a/src/test/rustdoc/issue-33069.rs b/src/test/rustdoc/issue-33069.rs new file mode 100644 index 00000000000..cd227fdef56 --- /dev/null +++ b/src/test/rustdoc/issue-33069.rs @@ -0,0 +1,20 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +pub trait Bar {} + +#[doc(hidden)] +pub mod hidden { + pub struct Foo; +} + +// @has issue_33069/trait.Bar.html +// @!has - '//code' 'impl Bar for Foo' +impl Bar for hidden::Foo {} From 84654fa4bf8e532469787889efa01b59a3c98aa0 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Mon, 18 Apr 2016 20:08:27 +0200 Subject: [PATCH 03/15] Split core::iter module implementation into parts split iter.rs into a directory of (implementation private) modules. + mod Adaptor structs - Private fields need to be available both for them and Iterator + iterator (Iterator trait) + traits (FromIterator, traits but Iterator itself) + range (range related) + sources (Repeat, Once, Empty) --- src/libcore/iter.rs | 5012 ---------------------------------- src/libcore/iter/iterator.rs | 2109 ++++++++++++++ src/libcore/iter/mod.rs | 1657 +++++++++++ src/libcore/iter/range.rs | 548 ++++ src/libcore/iter/sources.rs | 270 ++ src/libcore/iter/traits.rs | 526 ++++ 6 files changed, 5110 insertions(+), 5012 deletions(-) delete mode 100644 src/libcore/iter.rs create mode 100644 src/libcore/iter/iterator.rs create mode 100644 src/libcore/iter/mod.rs create mode 100644 src/libcore/iter/range.rs create mode 100644 src/libcore/iter/sources.rs create mode 100644 src/libcore/iter/traits.rs diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs deleted file mode 100644 index 69f10d197f7..00000000000 --- a/src/libcore/iter.rs +++ /dev/null @@ -1,5012 +0,0 @@ -// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -//! Composable external iteration. -//! -//! If you've found yourself with a collection of some kind, and needed to -//! perform an operation on the elements of said collection, you'll quickly run -//! into 'iterators'. Iterators are heavily used in idiomatic Rust code, so -//! it's worth becoming familiar with them. -//! -//! Before explaining more, let's talk about how this module is structured: -//! -//! # Organization -//! -//! This module is largely organized by type: -//! -//! * [Traits] are the core portion: these traits define what kind of iterators -//! exist and what you can do with them. The methods of these traits are worth -//! putting some extra study time into. -//! * [Functions] provide some helpful ways to create some basic iterators. -//! * [Structs] are often the return types of the various methods on this -//! module's traits. You'll usually want to look at the method that creates -//! the `struct`, rather than the `struct` itself. For more detail about why, -//! see '[Implementing Iterator](#implementing-iterator)'. -//! -//! [Traits]: #traits -//! [Functions]: #functions -//! [Structs]: #structs -//! -//! That's it! Let's dig into iterators. -//! -//! # Iterator -//! -//! The heart and soul of this module is the [`Iterator`] trait. The core of -//! [`Iterator`] looks like this: -//! -//! ``` -//! trait Iterator { -//! type Item; -//! fn next(&mut self) -> Option; -//! } -//! ``` -//! -//! An iterator has a method, [`next()`], which when called, returns an -//! [`Option`]``. [`next()`] will return `Some(Item)` as long as there -//! are elements, and once they've all been exhausted, will return `None` to -//! indicate that iteration is finished. Individual iterators may choose to -//! resume iteration, and so calling [`next()`] again may or may not eventually -//! start returning `Some(Item)` again at some point. -//! -//! [`Iterator`]'s full definition includes a number of other methods as well, -//! but they are default methods, built on top of [`next()`], and so you get -//! them for free. -//! -//! Iterators are also composable, and it's common to chain them together to do -//! more complex forms of processing. See the [Adapters](#adapters) section -//! below for more details. -//! -//! [`Iterator`]: trait.Iterator.html -//! [`next()`]: trait.Iterator.html#tymethod.next -//! [`Option`]: ../../std/option/enum.Option.html -//! -//! # The three forms of iteration -//! -//! There are three common methods which can create iterators from a collection: -//! -//! * `iter()`, which iterates over `&T`. -//! * `iter_mut()`, which iterates over `&mut T`. -//! * `into_iter()`, which iterates over `T`. -//! -//! Various things in the standard library may implement one or more of the -//! three, where appropriate. -//! -//! # Implementing Iterator -//! -//! Creating an iterator of your own involves two steps: creating a `struct` to -//! hold the iterator's state, and then `impl`ementing [`Iterator`] for that -//! `struct`. This is why there are so many `struct`s in this module: there is -//! one for each iterator and iterator adapter. -//! -//! Let's make an iterator named `Counter` which counts from `1` to `5`: -//! -//! ``` -//! // First, the struct: -//! -//! /// An iterator which counts from one to five -//! struct Counter { -//! count: usize, -//! } -//! -//! // we want our count to start at one, so let's add a new() method to help. -//! // This isn't strictly necessary, but is convenient. Note that we start -//! // `count` at zero, we'll see why in `next()`'s implementation below. -//! impl Counter { -//! fn new() -> Counter { -//! Counter { count: 0 } -//! } -//! } -//! -//! // Then, we implement `Iterator` for our `Counter`: -//! -//! impl Iterator for Counter { -//! // we will be counting with usize -//! type Item = usize; -//! -//! // next() is the only required method -//! fn next(&mut self) -> Option { -//! // increment our count. This is why we started at zero. -//! self.count += 1; -//! -//! // check to see if we've finished counting or not. -//! if self.count < 6 { -//! Some(self.count) -//! } else { -//! None -//! } -//! } -//! } -//! -//! // And now we can use it! -//! -//! let mut counter = Counter::new(); -//! -//! let x = counter.next().unwrap(); -//! println!("{}", x); -//! -//! let x = counter.next().unwrap(); -//! println!("{}", x); -//! -//! let x = counter.next().unwrap(); -//! println!("{}", x); -//! -//! let x = counter.next().unwrap(); -//! println!("{}", x); -//! -//! let x = counter.next().unwrap(); -//! println!("{}", x); -//! ``` -//! -//! This will print `1` through `5`, each on their own line. -//! -//! Calling `next()` this way gets repetitive. Rust has a construct which can -//! call `next()` on your iterator, until it reaches `None`. Let's go over that -//! next. -//! -//! # for Loops and IntoIterator -//! -//! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic -//! example of `for`: -//! -//! ``` -//! let values = vec![1, 2, 3, 4, 5]; -//! -//! for x in values { -//! println!("{}", x); -//! } -//! ``` -//! -//! This will print the numbers one through five, each on their own line. But -//! you'll notice something here: we never called anything on our vector to -//! produce an iterator. What gives? -//! -//! There's a trait in the standard library for converting something into an -//! iterator: [`IntoIterator`]. This trait has one method, [`into_iter()`], -//! which converts the thing implementing [`IntoIterator`] into an iterator. -//! Let's take a look at that `for` loop again, and what the compiler converts -//! it into: -//! -//! [`IntoIterator`]: trait.IntoIterator.html -//! [`into_iter()`]: trait.IntoIterator.html#tymethod.into_iter -//! -//! ``` -//! let values = vec![1, 2, 3, 4, 5]; -//! -//! for x in values { -//! println!("{}", x); -//! } -//! ``` -//! -//! Rust de-sugars this into: -//! -//! ``` -//! let values = vec![1, 2, 3, 4, 5]; -//! { -//! let result = match IntoIterator::into_iter(values) { -//! mut iter => loop { -//! match iter.next() { -//! Some(x) => { println!("{}", x); }, -//! None => break, -//! } -//! }, -//! }; -//! result -//! } -//! ``` -//! -//! First, we call `into_iter()` on the value. Then, we match on the iterator -//! that returns, calling [`next()`] over and over until we see a `None`. At -//! that point, we `break` out of the loop, and we're done iterating. -//! -//! There's one more subtle bit here: the standard library contains an -//! interesting implementation of [`IntoIterator`]: -//! -//! ```ignore -//! impl IntoIterator for I -//! ``` -//! -//! In other words, all [`Iterator`]s implement [`IntoIterator`], by just -//! returning themselves. This means two things: -//! -//! 1. If you're writing an [`Iterator`], you can use it with a `for` loop. -//! 2. If you're creating a collection, implementing [`IntoIterator`] for it -//! will allow your collection to be used with the `for` loop. -//! -//! # Adapters -//! -//! Functions which take an [`Iterator`] and return another [`Iterator`] are -//! often called 'iterator adapters', as they're a form of the 'adapter -//! pattern'. -//! -//! Common iterator adapters include [`map()`], [`take()`], and [`collect()`]. -//! For more, see their documentation. -//! -//! [`map()`]: trait.Iterator.html#method.map -//! [`take()`]: trait.Iterator.html#method.take -//! [`collect()`]: trait.Iterator.html#method.collect -//! -//! # Laziness -//! -//! Iterators (and iterator [adapters](#adapters)) are *lazy*. This means that -//! just creating an iterator doesn't _do_ a whole lot. Nothing really happens -//! until you call [`next()`]. This is sometimes a source of confusion when -//! creating an iterator solely for its side effects. For example, the [`map()`] -//! method calls a closure on each element it iterates over: -//! -//! ``` -//! # #![allow(unused_must_use)] -//! let v = vec![1, 2, 3, 4, 5]; -//! v.iter().map(|x| println!("{}", x)); -//! ``` -//! -//! This will not print any values, as we only created an iterator, rather than -//! using it. The compiler will warn us about this kind of behavior: -//! -//! ```text -//! warning: unused result which must be used: iterator adaptors are lazy and -//! do nothing unless consumed -//! ``` -//! -//! The idiomatic way to write a [`map()`] for its side effects is to use a -//! `for` loop instead: -//! -//! ``` -//! let v = vec![1, 2, 3, 4, 5]; -//! -//! for x in &v { -//! println!("{}", x); -//! } -//! ``` -//! -//! [`map()`]: trait.Iterator.html#method.map -//! -//! The two most common ways to evaluate an iterator are to use a `for` loop -//! like this, or using the [`collect()`] adapter to produce a new collection. -//! -//! [`collect()`]: trait.Iterator.html#method.collect -//! -//! # Infinity -//! -//! Iterators do not have to be finite. As an example, an open-ended range is -//! an infinite iterator: -//! -//! ``` -//! let numbers = 0..; -//! ``` -//! -//! It is common to use the [`take()`] iterator adapter to turn an infinite -//! iterator into a finite one: -//! -//! ``` -//! let numbers = 0..; -//! let five_numbers = numbers.take(5); -//! -//! for number in five_numbers { -//! println!("{}", number); -//! } -//! ``` -//! -//! This will print the numbers `0` through `4`, each on their own line. -//! -//! [`take()`]: trait.Iterator.html#method.take - -#![stable(feature = "rust1", since = "1.0.0")] - -use clone::Clone; -use cmp; -use cmp::{Ord, PartialOrd, PartialEq, Ordering}; -use default::Default; -use fmt; -use marker; -use mem; -use num::{Zero, One}; -use ops::{self, Add, Sub, FnMut, Mul}; -use option::Option::{self, Some, None}; -use marker::Sized; -use usize; - -fn _assert_is_object_safe(_: &Iterator) {} - -/// An interface for dealing with iterators. -/// -/// This is the main iterator trait. For more about the concept of iterators -/// generally, please see the [module-level documentation]. In particular, you -/// may want to know how to [implement `Iterator`][impl]. -/// -/// [module-level documentation]: index.html -/// [impl]: index.html#implementing-iterator -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \ - `.iter()` or a similar method"] -pub trait Iterator { - /// The type of the elements being iterated over. - #[stable(feature = "rust1", since = "1.0.0")] - type Item; - - /// Advances the iterator and returns the next value. - /// - /// Returns `None` when iteration is finished. Individual iterator - /// implementations may choose to resume iteration, and so calling `next()` - /// again may or may not eventually start returning `Some(Item)` again at some - /// point. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// // A call to next() returns the next value... - /// assert_eq!(Some(&1), iter.next()); - /// assert_eq!(Some(&2), iter.next()); - /// assert_eq!(Some(&3), iter.next()); - /// - /// // ... and then None once it's over. - /// assert_eq!(None, iter.next()); - /// - /// // More calls may or may not return None. Here, they always will. - /// assert_eq!(None, iter.next()); - /// assert_eq!(None, iter.next()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn next(&mut self) -> Option; - - /// Returns the bounds on the remaining length of the iterator. - /// - /// Specifically, `size_hint()` returns a tuple where the first element - /// is the lower bound, and the second element is the upper bound. - /// - /// The second half of the tuple that is returned is an `Option`. A - /// `None` here means that either there is no known upper bound, or the - /// upper bound is larger than `usize`. - /// - /// # Implementation notes - /// - /// It is not enforced that an iterator implementation yields the declared - /// number of elements. A buggy iterator may yield less than the lower bound - /// or more than the upper bound of elements. - /// - /// `size_hint()` is primarily intended to be used for optimizations such as - /// reserving space for the elements of the iterator, but must not be - /// trusted to e.g. omit bounds checks in unsafe code. An incorrect - /// implementation of `size_hint()` should not lead to memory safety - /// violations. - /// - /// That said, the implementation should provide a correct estimation, - /// because otherwise it would be a violation of the trait's protocol. - /// - /// The default implementation returns `(0, None)` which is correct for any - /// iterator. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// let iter = a.iter(); - /// - /// assert_eq!((3, Some(3)), iter.size_hint()); - /// ``` - /// - /// A more complex example: - /// - /// ``` - /// // The even numbers from zero to ten. - /// let iter = (0..10).filter(|x| x % 2 == 0); - /// - /// // We might iterate from zero to ten times. Knowing that it's five - /// // exactly wouldn't be possible without executing filter(). - /// assert_eq!((0, Some(10)), iter.size_hint()); - /// - /// // Let's add one five more numbers with chain() - /// let iter = (0..10).filter(|x| x % 2 == 0).chain(15..20); - /// - /// // now both bounds are increased by five - /// assert_eq!((5, Some(15)), iter.size_hint()); - /// ``` - /// - /// Returning `None` for an upper bound: - /// - /// ``` - /// // an infinite iterator has no upper bound - /// let iter = 0..; - /// - /// assert_eq!((0, None), iter.size_hint()); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn size_hint(&self) -> (usize, Option) { (0, None) } - - /// Consumes the iterator, counting the number of iterations and returning it. - /// - /// This method will evaluate the iterator until its [`next()`] returns - /// `None`. Once `None` is encountered, `count()` returns the number of - /// times it called [`next()`]. - /// - /// [`next()`]: #tymethod.next - /// - /// # Overflow Behavior - /// - /// The method does no guarding against overflows, so counting elements of - /// an iterator with more than `usize::MAX` elements either produces the - /// wrong result or panics. If debug assertions are enabled, a panic is - /// guaranteed. - /// - /// # Panics - /// - /// This function might panic if the iterator has more than `usize::MAX` - /// elements. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().count(), 3); - /// - /// let a = [1, 2, 3, 4, 5]; - /// assert_eq!(a.iter().count(), 5); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn count(self) -> usize where Self: Sized { - // Might overflow. - self.fold(0, |cnt, _| cnt + 1) - } - - /// Consumes the iterator, returning the last element. - /// - /// This method will evaluate the iterator until it returns `None`. While - /// doing so, it keeps track of the current element. After `None` is - /// returned, `last()` will then return the last element it saw. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().last(), Some(&3)); - /// - /// let a = [1, 2, 3, 4, 5]; - /// assert_eq!(a.iter().last(), Some(&5)); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn last(self) -> Option where Self: Sized { - let mut last = None; - for x in self { last = Some(x); } - last - } - - /// Consumes the `n` first elements of the iterator, then returns the - /// `next()` one. - /// - /// This method will evaluate the iterator `n` times, discarding those elements. - /// After it does so, it will call [`next()`] and return its value. - /// - /// [`next()`]: #tymethod.next - /// - /// Like most indexing operations, the count starts from zero, so `nth(0)` - /// returns the first value, `nth(1)` the second, and so on. - /// - /// `nth()` will return `None` if `n` is larger than the length of the - /// iterator. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().nth(1), Some(&2)); - /// ``` - /// - /// Calling `nth()` multiple times doesn't rewind the iterator: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// assert_eq!(iter.nth(1), Some(&2)); - /// assert_eq!(iter.nth(1), None); - /// ``` - /// - /// Returning `None` if there are less than `n` elements: - /// - /// ``` - /// let a = [1, 2, 3]; - /// assert_eq!(a.iter().nth(10), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn nth(&mut self, mut n: usize) -> Option where Self: Sized { - for x in self { - if n == 0 { return Some(x) } - n -= 1; - } - None - } - - /// Takes two iterators and creates a new iterator over both in sequence. - /// - /// `chain()` will return a new iterator which will first iterate over - /// values from the first iterator and then over values from the second - /// iterator. - /// - /// In other words, it links two iterators together, in a chain. 🔗 - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a1 = [1, 2, 3]; - /// let a2 = [4, 5, 6]; - /// - /// let mut iter = a1.iter().chain(a2.iter()); - /// - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), Some(&4)); - /// assert_eq!(iter.next(), Some(&5)); - /// assert_eq!(iter.next(), Some(&6)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Since the argument to `chain()` uses [`IntoIterator`], we can pass - /// anything that can be converted into an [`Iterator`], not just an - /// [`Iterator`] itself. For example, slices (`&[T]`) implement - /// [`IntoIterator`], and so can be passed to `chain()` directly: - /// - /// [`IntoIterator`]: trait.IntoIterator.html - /// [`Iterator`]: trait.Iterator.html - /// - /// ``` - /// let s1 = &[1, 2, 3]; - /// let s2 = &[4, 5, 6]; - /// - /// let mut iter = s1.iter().chain(s2); - /// - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), Some(&4)); - /// assert_eq!(iter.next(), Some(&5)); - /// assert_eq!(iter.next(), Some(&6)); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn chain(self, other: U) -> Chain where - Self: Sized, U: IntoIterator, - { - Chain{a: self, b: other.into_iter(), state: ChainState::Both} - } - - /// 'Zips up' two iterators into a single iterator of pairs. - /// - /// `zip()` returns a new iterator that will iterate over two other - /// iterators, returning a tuple where the first element comes from the - /// first iterator, and the second element comes from the second iterator. - /// - /// In other words, it zips two iterators together, into a single one. - /// - /// When either iterator returns `None`, all further calls to `next()` - /// will return `None`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a1 = [1, 2, 3]; - /// let a2 = [4, 5, 6]; - /// - /// let mut iter = a1.iter().zip(a2.iter()); - /// - /// assert_eq!(iter.next(), Some((&1, &4))); - /// assert_eq!(iter.next(), Some((&2, &5))); - /// assert_eq!(iter.next(), Some((&3, &6))); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Since the argument to `zip()` uses [`IntoIterator`], we can pass - /// anything that can be converted into an [`Iterator`], not just an - /// [`Iterator`] itself. For example, slices (`&[T]`) implement - /// [`IntoIterator`], and so can be passed to `zip()` directly: - /// - /// [`IntoIterator`]: trait.IntoIterator.html - /// [`Iterator`]: trait.Iterator.html - /// - /// ``` - /// let s1 = &[1, 2, 3]; - /// let s2 = &[4, 5, 6]; - /// - /// let mut iter = s1.iter().zip(s2); - /// - /// assert_eq!(iter.next(), Some((&1, &4))); - /// assert_eq!(iter.next(), Some((&2, &5))); - /// assert_eq!(iter.next(), Some((&3, &6))); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// `zip()` is often used to zip an infinite iterator to a finite one. - /// This works because the finite iterator will eventually return `None`, - /// ending the zipper. Zipping with `(0..)` can look a lot like [`enumerate()`]: - /// - /// ``` - /// let enumerate: Vec<_> = "foo".chars().enumerate().collect(); - /// - /// let zipper: Vec<_> = (0..).zip("foo".chars()).collect(); - /// - /// assert_eq!((0, 'f'), enumerate[0]); - /// assert_eq!((0, 'f'), zipper[0]); - /// - /// assert_eq!((1, 'o'), enumerate[1]); - /// assert_eq!((1, 'o'), zipper[1]); - /// - /// assert_eq!((2, 'o'), enumerate[2]); - /// assert_eq!((2, 'o'), zipper[2]); - /// ``` - /// - /// [`enumerate()`]: trait.Iterator.html#method.enumerate - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn zip(self, other: U) -> Zip where - Self: Sized, U: IntoIterator - { - Zip{a: self, b: other.into_iter()} - } - - /// Takes a closure and creates an iterator which calls that closure on each - /// element. - /// - /// `map()` transforms one iterator into another, by means of its argument: - /// something that implements `FnMut`. It produces a new iterator which - /// calls this closure on each element of the original iterator. - /// - /// If you are good at thinking in types, you can think of `map()` like this: - /// If you have an iterator that gives you elements of some type `A`, and - /// you want an iterator of some other type `B`, you can use `map()`, - /// passing a closure that takes an `A` and returns a `B`. - /// - /// `map()` is conceptually similar to a [`for`] loop. However, as `map()` is - /// lazy, it is best used when you're already working with other iterators. - /// If you're doing some sort of looping for a side effect, it's considered - /// more idiomatic to use [`for`] than `map()`. - /// - /// [`for`]: ../../book/loops.html#for - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.into_iter().map(|x| 2 * x); - /// - /// assert_eq!(iter.next(), Some(2)); - /// assert_eq!(iter.next(), Some(4)); - /// assert_eq!(iter.next(), Some(6)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// If you're doing some sort of side effect, prefer [`for`] to `map()`: - /// - /// ``` - /// # #![allow(unused_must_use)] - /// // don't do this: - /// (0..5).map(|x| println!("{}", x)); - /// - /// // it won't even execute, as it is lazy. Rust will warn you about this. - /// - /// // Instead, use for: - /// for x in 0..5 { - /// println!("{}", x); - /// } - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn map(self, f: F) -> Map where - Self: Sized, F: FnMut(Self::Item) -> B, - { - Map{iter: self, f: f} - } - - /// Creates an iterator which uses a closure to determine if an element - /// should be yielded. - /// - /// The closure must return `true` or `false`. `filter()` creates an - /// iterator which calls this closure on each element. If the closure - /// returns `true`, then the element is returned. If the closure returns - /// `false`, it will try again, and call the closure on the next element, - /// seeing if it passes the test. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [0i32, 1, 2]; - /// - /// let mut iter = a.into_iter().filter(|x| x.is_positive()); - /// - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Because the closure passed to `filter()` takes a reference, and many - /// iterators iterate over references, this leads to a possibly confusing - /// situation, where the type of the closure is a double reference: - /// - /// ``` - /// let a = [0, 1, 2]; - /// - /// let mut iter = a.into_iter().filter(|x| **x > 1); // need two *s! - /// - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// It's common to instead use destructuring on the argument to strip away - /// one: - /// - /// ``` - /// let a = [0, 1, 2]; - /// - /// let mut iter = a.into_iter().filter(|&x| *x > 1); // both & and * - /// - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// or both: - /// - /// ``` - /// let a = [0, 1, 2]; - /// - /// let mut iter = a.into_iter().filter(|&&x| x > 1); // two &s - /// - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// of these layers. - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn filter

(self, predicate: P) -> Filter where - Self: Sized, P: FnMut(&Self::Item) -> bool, - { - Filter{iter: self, predicate: predicate} - } - - /// Creates an iterator that both filters and maps. - /// - /// The closure must return an [`Option`]. `filter_map()` creates an - /// iterator which calls this closure on each element. If the closure - /// returns `Some(element)`, then that element is returned. If the - /// closure returns `None`, it will try again, and call the closure on the - /// next element, seeing if it will return `Some`. - /// - /// [`Option`]: ../../std/option/enum.Option.html - /// - /// Why `filter_map()` and not just [`filter()`].[`map()`]? The key is in this - /// part: - /// - /// [`filter()`]: #method.filter - /// [`map()`]: #method.map - /// - /// > If the closure returns `Some(element)`, then that element is returned. - /// - /// In other words, it removes the [`Option`] layer automatically. If your - /// mapping is already returning an [`Option`] and you want to skip over - /// `None`s, then `filter_map()` is much, much nicer to use. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = ["1", "2", "lol"]; - /// - /// let mut iter = a.iter().filter_map(|s| s.parse().ok()); - /// - /// assert_eq!(iter.next(), Some(1)); - /// assert_eq!(iter.next(), Some(2)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Here's the same example, but with [`filter()`] and [`map()`]: - /// - /// ``` - /// let a = ["1", "2", "lol"]; - /// - /// let mut iter = a.iter() - /// .map(|s| s.parse().ok()) - /// .filter(|s| s.is_some()); - /// - /// assert_eq!(iter.next(), Some(Some(1))); - /// assert_eq!(iter.next(), Some(Some(2))); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// There's an extra layer of `Some` in there. - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn filter_map(self, f: F) -> FilterMap where - Self: Sized, F: FnMut(Self::Item) -> Option, - { - FilterMap { iter: self, f: f } - } - - /// Creates an iterator which gives the current iteration count as well as - /// the next value. - /// - /// The iterator returned yields pairs `(i, val)`, where `i` is the - /// current index of iteration and `val` is the value returned by the - /// iterator. - /// - /// `enumerate()` keeps its count as a [`usize`]. If you want to count by a - /// different sized integer, the [`zip()`] function provides similar - /// functionality. - /// - /// [`usize`]: ../../std/primitive.usize.html - /// [`zip()`]: #method.zip - /// - /// # Overflow Behavior - /// - /// The method does no guarding against overflows, so enumerating more than - /// [`usize::MAX`] elements either produces the wrong result or panics. If - /// debug assertions are enabled, a panic is guaranteed. - /// - /// [`usize::MAX`]: ../../std/usize/constant.MAX.html - /// - /// # Panics - /// - /// The returned iterator might panic if the to-be-returned index would - /// overflow a `usize`. - /// - /// # Examples - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter().enumerate(); - /// - /// assert_eq!(iter.next(), Some((0, &1))); - /// assert_eq!(iter.next(), Some((1, &2))); - /// assert_eq!(iter.next(), Some((2, &3))); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn enumerate(self) -> Enumerate where Self: Sized { - Enumerate { iter: self, count: 0 } - } - - /// Creates an iterator which can use `peek` to look at the next element of - /// the iterator without consuming it. - /// - /// Adds a [`peek()`] method to an iterator. See its documentation for - /// more information. - /// - /// Note that the underlying iterator is still advanced when `peek` is - /// called for the first time: In order to retrieve the next element, - /// `next` is called on the underlying iterator, hence any side effects of - /// the `next` method will occur. - /// - /// [`peek()`]: struct.Peekable.html#method.peek - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let xs = [1, 2, 3]; - /// - /// let mut iter = xs.iter().peekable(); - /// - /// // peek() lets us see into the future - /// assert_eq!(iter.peek(), Some(&&1)); - /// assert_eq!(iter.next(), Some(&1)); - /// - /// assert_eq!(iter.next(), Some(&2)); - /// - /// // we can peek() multiple times, the iterator won't advance - /// assert_eq!(iter.peek(), Some(&&3)); - /// assert_eq!(iter.peek(), Some(&&3)); - /// - /// assert_eq!(iter.next(), Some(&3)); - /// - /// // after the iterator is finished, so is peek() - /// assert_eq!(iter.peek(), None); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn peekable(self) -> Peekable where Self: Sized { - Peekable{iter: self, peeked: None} - } - - /// Creates an iterator that [`skip()`]s elements based on a predicate. - /// - /// [`skip()`]: #method.skip - /// - /// `skip_while()` takes a closure as an argument. It will call this - /// closure on each element of the iterator, and ignore elements - /// until it returns `false`. - /// - /// After `false` is returned, `skip_while()`'s job is over, and the - /// rest of the elements are yielded. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [-1i32, 0, 1]; - /// - /// let mut iter = a.into_iter().skip_while(|x| x.is_negative()); - /// - /// assert_eq!(iter.next(), Some(&0)); - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Because the closure passed to `skip_while()` takes a reference, and many - /// iterators iterate over references, this leads to a possibly confusing - /// situation, where the type of the closure is a double reference: - /// - /// ``` - /// let a = [-1, 0, 1]; - /// - /// let mut iter = a.into_iter().skip_while(|x| **x < 0); // need two *s! - /// - /// assert_eq!(iter.next(), Some(&0)); - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Stopping after an initial `false`: - /// - /// ``` - /// let a = [-1, 0, 1, -2]; - /// - /// let mut iter = a.into_iter().skip_while(|x| **x < 0); - /// - /// assert_eq!(iter.next(), Some(&0)); - /// assert_eq!(iter.next(), Some(&1)); - /// - /// // while this would have been false, since we already got a false, - /// // skip_while() isn't used any more - /// assert_eq!(iter.next(), Some(&-2)); - /// - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn skip_while

(self, predicate: P) -> SkipWhile where - Self: Sized, P: FnMut(&Self::Item) -> bool, - { - SkipWhile{iter: self, flag: false, predicate: predicate} - } - - /// Creates an iterator that yields elements based on a predicate. - /// - /// `take_while()` takes a closure as an argument. It will call this - /// closure on each element of the iterator, and yield elements - /// while it returns `true`. - /// - /// After `false` is returned, `take_while()`'s job is over, and the - /// rest of the elements are ignored. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [-1i32, 0, 1]; - /// - /// let mut iter = a.into_iter().take_while(|x| x.is_negative()); - /// - /// assert_eq!(iter.next(), Some(&-1)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Because the closure passed to `take_while()` takes a reference, and many - /// iterators iterate over references, this leads to a possibly confusing - /// situation, where the type of the closure is a double reference: - /// - /// ``` - /// let a = [-1, 0, 1]; - /// - /// let mut iter = a.into_iter().take_while(|x| **x < 0); // need two *s! - /// - /// assert_eq!(iter.next(), Some(&-1)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Stopping after an initial `false`: - /// - /// ``` - /// let a = [-1, 0, 1, -2]; - /// - /// let mut iter = a.into_iter().take_while(|x| **x < 0); - /// - /// assert_eq!(iter.next(), Some(&-1)); - /// - /// // We have more elements that are less than zero, but since we already - /// // got a false, take_while() isn't used any more - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// Because `take_while()` needs to look at the value in order to see if it - /// should be included or not, consuming iterators will see that it is - /// removed: - /// - /// ``` - /// let a = [1, 2, 3, 4]; - /// let mut iter = a.into_iter(); - /// - /// let result: Vec = iter.by_ref() - /// .take_while(|n| **n != 3) - /// .cloned() - /// .collect(); - /// - /// assert_eq!(result, &[1, 2]); - /// - /// let result: Vec = iter.cloned().collect(); - /// - /// assert_eq!(result, &[4]); - /// ``` - /// - /// The `3` is no longer there, because it was consumed in order to see if - /// the iteration should stop, but wasn't placed back into the iterator or - /// some similar thing. - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn take_while

(self, predicate: P) -> TakeWhile where - Self: Sized, P: FnMut(&Self::Item) -> bool, - { - TakeWhile{iter: self, flag: false, predicate: predicate} - } - - /// Creates an iterator that skips the first `n` elements. - /// - /// After they have been consumed, the rest of the elements are yielded. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter().skip(2); - /// - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn skip(self, n: usize) -> Skip where Self: Sized { - Skip{iter: self, n: n} - } - - /// Creates an iterator that yields its first `n` elements. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter().take(2); - /// - /// assert_eq!(iter.next(), Some(&1)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), None); - /// ``` - /// - /// `take()` is often used with an infinite iterator, to make it finite: - /// - /// ``` - /// let mut iter = (0..).take(3); - /// - /// assert_eq!(iter.next(), Some(0)); - /// assert_eq!(iter.next(), Some(1)); - /// assert_eq!(iter.next(), Some(2)); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn take(self, n: usize) -> Take where Self: Sized, { - Take{iter: self, n: n} - } - - /// An iterator adaptor similar to [`fold()`] that holds internal state and - /// produces a new iterator. - /// - /// [`fold()`]: #method.fold - /// - /// `scan()` takes two arguments: an initial value which seeds the internal - /// state, and a closure with two arguments, the first being a mutable - /// reference to the internal state and the second an iterator element. - /// The closure can assign to the internal state to share state between - /// iterations. - /// - /// On iteration, the closure will be applied to each element of the - /// iterator and the return value from the closure, an [`Option`], is - /// yielded by the iterator. - /// - /// [`Option`]: ../../std/option/enum.Option.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter().scan(1, |state, &x| { - /// // each iteration, we'll multiply the state by the element - /// *state = *state * x; - /// - /// // the value passed on to the next iteration - /// Some(*state) - /// }); - /// - /// assert_eq!(iter.next(), Some(1)); - /// assert_eq!(iter.next(), Some(2)); - /// assert_eq!(iter.next(), Some(6)); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn scan(self, initial_state: St, f: F) -> Scan - where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option, - { - Scan{iter: self, f: f, state: initial_state} - } - - /// Creates an iterator that works like map, but flattens nested structure. - /// - /// The [`map()`] adapter is very useful, but only when the closure - /// argument produces values. If it produces an iterator instead, there's - /// an extra layer of indirection. `flat_map()` will remove this extra layer - /// on its own. - /// - /// [`map()`]: #method.map - /// - /// Another way of thinking about `flat_map()`: [`map()`]'s closure returns - /// one item for each element, and `flat_map()`'s closure returns an - /// iterator for each element. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let words = ["alpha", "beta", "gamma"]; - /// - /// // chars() returns an iterator - /// let merged: String = words.iter() - /// .flat_map(|s| s.chars()) - /// .collect(); - /// assert_eq!(merged, "alphabetagamma"); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn flat_map(self, f: F) -> FlatMap - where Self: Sized, U: IntoIterator, F: FnMut(Self::Item) -> U, - { - FlatMap{iter: self, f: f, frontiter: None, backiter: None } - } - - /// Creates an iterator which ends after the first `None`. - /// - /// After an iterator returns `None`, future calls may or may not yield - /// `Some(T)` again. `fuse()` adapts an iterator, ensuring that after a - /// `None` is given, it will always return `None` forever. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// // an iterator which alternates between Some and None - /// struct Alternate { - /// state: i32, - /// } - /// - /// impl Iterator for Alternate { - /// type Item = i32; - /// - /// fn next(&mut self) -> Option { - /// let val = self.state; - /// self.state = self.state + 1; - /// - /// // if it's even, Some(i32), else None - /// if val % 2 == 0 { - /// Some(val) - /// } else { - /// None - /// } - /// } - /// } - /// - /// let mut iter = Alternate { state: 0 }; - /// - /// // we can see our iterator going back and forth - /// assert_eq!(iter.next(), Some(0)); - /// assert_eq!(iter.next(), None); - /// assert_eq!(iter.next(), Some(2)); - /// assert_eq!(iter.next(), None); - /// - /// // however, once we fuse it... - /// let mut iter = iter.fuse(); - /// - /// assert_eq!(iter.next(), Some(4)); - /// assert_eq!(iter.next(), None); - /// - /// // it will always return None after the first time. - /// assert_eq!(iter.next(), None); - /// assert_eq!(iter.next(), None); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn fuse(self) -> Fuse where Self: Sized { - Fuse{iter: self, done: false} - } - - /// Do something with each element of an iterator, passing the value on. - /// - /// When using iterators, you'll often chain several of them together. - /// While working on such code, you might want to check out what's - /// happening at various parts in the pipeline. To do that, insert - /// a call to `inspect()`. - /// - /// It's much more common for `inspect()` to be used as a debugging tool - /// than to exist in your final code, but never say never. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 4, 2, 3]; - /// - /// // this iterator sequence is complex. - /// let sum = a.iter() - /// .cloned() - /// .filter(|&x| x % 2 == 0) - /// .fold(0, |sum, i| sum + i); - /// - /// println!("{}", sum); - /// - /// // let's add some inspect() calls to investigate what's happening - /// let sum = a.iter() - /// .cloned() - /// .inspect(|x| println!("about to filter: {}", x)) - /// .filter(|&x| x % 2 == 0) - /// .inspect(|x| println!("made it through filter: {}", x)) - /// .fold(0, |sum, i| sum + i); - /// - /// println!("{}", sum); - /// ``` - /// - /// This will print: - /// - /// ```text - /// about to filter: 1 - /// about to filter: 4 - /// made it through filter: 4 - /// about to filter: 2 - /// made it through filter: 2 - /// about to filter: 3 - /// 6 - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn inspect(self, f: F) -> Inspect where - Self: Sized, F: FnMut(&Self::Item), - { - Inspect{iter: self, f: f} - } - - /// Borrows an iterator, rather than consuming it. - /// - /// This is useful to allow applying iterator adaptors while still - /// retaining ownership of the original iterator. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let iter = a.into_iter(); - /// - /// let sum: i32 = iter.take(5) - /// .fold(0, |acc, &i| acc + i ); - /// - /// assert_eq!(sum, 6); - /// - /// // if we try to use iter again, it won't work. The following line - /// // gives "error: use of moved value: `iter` - /// // assert_eq!(iter.next(), None); - /// - /// // let's try that again - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.into_iter(); - /// - /// // instead, we add in a .by_ref() - /// let sum: i32 = iter.by_ref() - /// .take(2) - /// .fold(0, |acc, &i| acc + i ); - /// - /// assert_eq!(sum, 3); - /// - /// // now this is just fine: - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), None); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn by_ref(&mut self) -> &mut Self where Self: Sized { self } - - /// Transforms an iterator into a collection. - /// - /// `collect()` can take anything iterable, and turn it into a relevant - /// collection. This is one of the more powerful methods in the standard - /// library, used in a variety of contexts. - /// - /// The most basic pattern in which `collect()` is used is to turn one - /// collection into another. You take a collection, call `iter()` on it, - /// do a bunch of transformations, and then `collect()` at the end. - /// - /// One of the keys to `collect()`'s power is that many things you might - /// not think of as 'collections' actually are. For example, a [`String`] - /// is a collection of [`char`]s. And a collection of [`Result`] can - /// be thought of as single `Result, E>`. See the examples - /// below for more. - /// - /// [`String`]: ../../std/string/struct.String.html - /// [`Result`]: ../../std/result/enum.Result.html - /// [`char`]: ../../std/primitive.char.html - /// - /// Because `collect()` is so general, it can cause problems with type - /// inference. As such, `collect()` is one of the few times you'll see - /// the syntax affectionately known as the 'turbofish': `::<>`. This - /// helps the inference algorithm understand specifically which collection - /// you're trying to collect into. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let doubled: Vec = a.iter() - /// .map(|&x| x * 2) - /// .collect(); - /// - /// assert_eq!(vec![2, 4, 6], doubled); - /// ``` - /// - /// Note that we needed the `: Vec` on the left-hand side. This is because - /// we could collect into, for example, a [`VecDeque`] instead: - /// - /// [`VecDeque`]: ../../std/collections/struct.VecDeque.html - /// - /// ``` - /// use std::collections::VecDeque; - /// - /// let a = [1, 2, 3]; - /// - /// let doubled: VecDeque = a.iter() - /// .map(|&x| x * 2) - /// .collect(); - /// - /// assert_eq!(2, doubled[0]); - /// assert_eq!(4, doubled[1]); - /// assert_eq!(6, doubled[2]); - /// ``` - /// - /// Using the 'turbofish' instead of annotating `doubled`: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let doubled = a.iter() - /// .map(|&x| x * 2) - /// .collect::>(); - /// - /// assert_eq!(vec![2, 4, 6], doubled); - /// ``` - /// - /// Because `collect()` cares about what you're collecting into, you can - /// still use a partial type hint, `_`, with the turbofish: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let doubled = a.iter() - /// .map(|&x| x * 2) - /// .collect::>(); - /// - /// assert_eq!(vec![2, 4, 6], doubled); - /// ``` - /// - /// Using `collect()` to make a [`String`]: - /// - /// ``` - /// let chars = ['g', 'd', 'k', 'k', 'n']; - /// - /// let hello: String = chars.iter() - /// .map(|&x| x as u8) - /// .map(|x| (x + 1) as char) - /// .collect(); - /// - /// assert_eq!("hello", hello); - /// ``` - /// - /// If you have a list of [`Result`]s, you can use `collect()` to - /// see if any of them failed: - /// - /// ``` - /// let results = [Ok(1), Err("nope"), Ok(3), Err("bad")]; - /// - /// let result: Result, &str> = results.iter().cloned().collect(); - /// - /// // gives us the first error - /// assert_eq!(Err("nope"), result); - /// - /// let results = [Ok(1), Ok(3)]; - /// - /// let result: Result, &str> = results.iter().cloned().collect(); - /// - /// // gives us the list of answers - /// assert_eq!(Ok(vec![1, 3]), result); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn collect>(self) -> B where Self: Sized { - FromIterator::from_iter(self) - } - - /// Consumes an iterator, creating two collections from it. - /// - /// The predicate passed to `partition()` can return `true`, or `false`. - /// `partition()` returns a pair, all of the elements for which it returned - /// `true`, and all of the elements for which it returned `false`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let (even, odd): (Vec, Vec) = a.into_iter() - /// .partition(|&n| n % 2 == 0); - /// - /// assert_eq!(even, vec![2]); - /// assert_eq!(odd, vec![1, 3]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn partition(self, mut f: F) -> (B, B) where - Self: Sized, - B: Default + Extend, - F: FnMut(&Self::Item) -> bool - { - let mut left: B = Default::default(); - let mut right: B = Default::default(); - - for x in self { - if f(&x) { - left.extend(Some(x)) - } else { - right.extend(Some(x)) - } - } - - (left, right) - } - - /// An iterator adaptor that applies a function, producing a single, final value. - /// - /// `fold()` takes two arguments: an initial value, and a closure with two - /// arguments: an 'accumulator', and an element. The closure returns the value that - /// the accumulator should have for the next iteration. - /// - /// The initial value is the value the accumulator will have on the first - /// call. - /// - /// After applying this closure to every element of the iterator, `fold()` - /// returns the accumulator. - /// - /// This operation is sometimes called 'reduce' or 'inject'. - /// - /// Folding is useful whenever you have a collection of something, and want - /// to produce a single value from it. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// // the sum of all of the elements of a - /// let sum = a.iter() - /// .fold(0, |acc, &x| acc + x); - /// - /// assert_eq!(sum, 6); - /// ``` - /// - /// Let's walk through each step of the iteration here: - /// - /// | element | acc | x | result | - /// |---------|-----|---|--------| - /// | | 0 | | | - /// | 1 | 0 | 1 | 1 | - /// | 2 | 1 | 2 | 3 | - /// | 3 | 3 | 3 | 6 | - /// - /// And so, our final result, `6`. - /// - /// It's common for people who haven't used iterators a lot to - /// use a `for` loop with a list of things to build up a result. Those - /// can be turned into `fold()`s: - /// - /// ``` - /// let numbers = [1, 2, 3, 4, 5]; - /// - /// let mut result = 0; - /// - /// // for loop: - /// for i in &numbers { - /// result = result + i; - /// } - /// - /// // fold: - /// let result2 = numbers.iter().fold(0, |acc, &x| acc + x); - /// - /// // they're the same - /// assert_eq!(result, result2); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn fold(self, init: B, mut f: F) -> B where - Self: Sized, F: FnMut(B, Self::Item) -> B, - { - let mut accum = init; - for x in self { - accum = f(accum, x); - } - accum - } - - /// Tests if every element of the iterator matches a predicate. - /// - /// `all()` takes a closure that returns `true` or `false`. It applies - /// this closure to each element of the iterator, and if they all return - /// `true`, then so does `all()`. If any of them return `false`, it - /// returns `false`. - /// - /// `all()` is short-circuiting; in other words, it will stop processing - /// as soon as it finds a `false`, given that no matter what else happens, - /// the result will also be `false`. - /// - /// An empty iterator returns `true`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// assert!(a.iter().all(|&x| x > 0)); - /// - /// assert!(!a.iter().all(|&x| x > 2)); - /// ``` - /// - /// Stopping at the first `false`: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// assert!(!iter.all(|&x| x != 2)); - /// - /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&3)); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn all(&mut self, mut f: F) -> bool where - Self: Sized, F: FnMut(Self::Item) -> bool - { - for x in self { - if !f(x) { - return false; - } - } - true - } - - /// Tests if any element of the iterator matches a predicate. - /// - /// `any()` takes a closure that returns `true` or `false`. It applies - /// this closure to each element of the iterator, and if any of them return - /// `true`, then so does `any()`. If they all return `false`, it - /// returns `false`. - /// - /// `any()` is short-circuiting; in other words, it will stop processing - /// as soon as it finds a `true`, given that no matter what else happens, - /// the result will also be `true`. - /// - /// An empty iterator returns `false`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// assert!(a.iter().any(|&x| x > 0)); - /// - /// assert!(!a.iter().any(|&x| x > 5)); - /// ``` - /// - /// Stopping at the first `true`: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// assert!(iter.any(|&x| x != 2)); - /// - /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&2)); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn any(&mut self, mut f: F) -> bool where - Self: Sized, - F: FnMut(Self::Item) -> bool - { - for x in self { - if f(x) { - return true; - } - } - false - } - - /// Searches for an element of an iterator that satisfies a predicate. - /// - /// `find()` takes a closure that returns `true` or `false`. It applies - /// this closure to each element of the iterator, and if any of them return - /// `true`, then `find()` returns `Some(element)`. If they all return - /// `false`, it returns `None`. - /// - /// `find()` is short-circuiting; in other words, it will stop processing - /// as soon as the closure returns `true`. - /// - /// Because `find()` takes a reference, and many iterators iterate over - /// references, this leads to a possibly confusing situation where the - /// argument is a double reference. You can see this effect in the - /// examples below, with `&&x`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// assert_eq!(a.iter().find(|&&x| x == 2), Some(&2)); - /// - /// assert_eq!(a.iter().find(|&&x| x == 5), None); - /// ``` - /// - /// Stopping at the first `true`: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// assert_eq!(iter.find(|&&x| x == 2), Some(&2)); - /// - /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&3)); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn find

(&mut self, mut predicate: P) -> Option where - Self: Sized, - P: FnMut(&Self::Item) -> bool, - { - for x in self { - if predicate(&x) { return Some(x) } - } - None - } - - /// Searches for an element in an iterator, returning its index. - /// - /// `position()` takes a closure that returns `true` or `false`. It applies - /// this closure to each element of the iterator, and if one of them - /// returns `true`, then `position()` returns `Some(index)`. If all of - /// them return `false`, it returns `None`. - /// - /// `position()` is short-circuiting; in other words, it will stop - /// processing as soon as it finds a `true`. - /// - /// # Overflow Behavior - /// - /// The method does no guarding against overflows, so if there are more - /// than `usize::MAX` non-matching elements, it either produces the wrong - /// result or panics. If debug assertions are enabled, a panic is - /// guaranteed. - /// - /// # Panics - /// - /// This function might panic if the iterator has more than `usize::MAX` - /// non-matching elements. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// assert_eq!(a.iter().position(|&x| x == 2), Some(1)); - /// - /// assert_eq!(a.iter().position(|&x| x == 5), None); - /// ``` - /// - /// Stopping at the first `true`: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// assert_eq!(iter.position(|&x| x == 2), Some(1)); - /// - /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&3)); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn position

(&mut self, mut predicate: P) -> Option where - Self: Sized, - P: FnMut(Self::Item) -> bool, - { - // `enumerate` might overflow. - for (i, x) in self.enumerate() { - if predicate(x) { - return Some(i); - } - } - None - } - - /// Searches for an element in an iterator from the right, returning its - /// index. - /// - /// `rposition()` takes a closure that returns `true` or `false`. It applies - /// this closure to each element of the iterator, starting from the end, - /// and if one of them returns `true`, then `rposition()` returns - /// `Some(index)`. If all of them return `false`, it returns `None`. - /// - /// `rposition()` is short-circuiting; in other words, it will stop - /// processing as soon as it finds a `true`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// assert_eq!(a.iter().rposition(|&x| x == 3), Some(2)); - /// - /// assert_eq!(a.iter().rposition(|&x| x == 5), None); - /// ``` - /// - /// Stopping at the first `true`: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter(); - /// - /// assert_eq!(iter.rposition(|&x| x == 2), Some(1)); - /// - /// // we can still use `iter`, as there are more elements. - /// assert_eq!(iter.next(), Some(&1)); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn rposition

(&mut self, mut predicate: P) -> Option where - P: FnMut(Self::Item) -> bool, - Self: Sized + ExactSizeIterator + DoubleEndedIterator - { - let mut i = self.len(); - - while let Some(v) = self.next_back() { - if predicate(v) { - return Some(i - 1); - } - // No need for an overflow check here, because `ExactSizeIterator` - // implies that the number of elements fits into a `usize`. - i -= 1; - } - None - } - - /// Returns the maximum element of an iterator. - /// - /// If the two elements are equally maximum, the latest element is - /// returned. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// assert_eq!(a.iter().max(), Some(&3)); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn max(self) -> Option where Self: Sized, Self::Item: Ord - { - select_fold1(self, - |_| (), - // switch to y even if it is only equal, to preserve - // stability. - |_, x, _, y| *x <= *y) - .map(|(_, x)| x) - } - - /// Returns the minimum element of an iterator. - /// - /// If the two elements are equally minimum, the first element is - /// returned. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// assert_eq!(a.iter().min(), Some(&1)); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn min(self) -> Option where Self: Sized, Self::Item: Ord - { - select_fold1(self, - |_| (), - // only switch to y if it is strictly smaller, to - // preserve stability. - |_, x, _, y| *x > *y) - .map(|(_, x)| x) - } - - /// Returns the element that gives the maximum value from the - /// specified function. - /// - /// Returns the rightmost element if the comparison determines two elements - /// to be equally maximum. - /// - /// # Examples - /// - /// ``` - /// let a = [-3_i32, 0, 1, 5, -10]; - /// assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10); - /// ``` - #[inline] - #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] - fn max_by_key(self, f: F) -> Option - where Self: Sized, F: FnMut(&Self::Item) -> B, - { - select_fold1(self, - f, - // switch to y even if it is only equal, to preserve - // stability. - |x_p, _, y_p, _| x_p <= y_p) - .map(|(_, x)| x) - } - - /// Returns the element that gives the minimum value from the - /// specified function. - /// - /// Returns the latest element if the comparison determines two elements - /// to be equally minimum. - /// - /// # Examples - /// - /// ``` - /// let a = [-3_i32, 0, 1, 5, -10]; - /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0); - /// ``` - #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] - fn min_by_key(self, f: F) -> Option - where Self: Sized, F: FnMut(&Self::Item) -> B, - { - select_fold1(self, - f, - // only switch to y if it is strictly smaller, to - // preserve stability. - |x_p, _, y_p, _| x_p > y_p) - .map(|(_, x)| x) - } - - /// Reverses an iterator's direction. - /// - /// Usually, iterators iterate from left to right. After using `rev()`, - /// an iterator will instead iterate from right to left. - /// - /// This is only possible if the iterator has an end, so `rev()` only - /// works on [`DoubleEndedIterator`]s. - /// - /// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html - /// - /// # Examples - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut iter = a.iter().rev(); - /// - /// assert_eq!(iter.next(), Some(&3)); - /// assert_eq!(iter.next(), Some(&2)); - /// assert_eq!(iter.next(), Some(&1)); - /// - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - fn rev(self) -> Rev where Self: Sized + DoubleEndedIterator { - Rev{iter: self} - } - - /// Converts an iterator of pairs into a pair of containers. - /// - /// `unzip()` consumes an entire iterator of pairs, producing two - /// collections: one from the left elements of the pairs, and one - /// from the right elements. - /// - /// This function is, in some sense, the opposite of [`zip()`]. - /// - /// [`zip()`]: #method.zip - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [(1, 2), (3, 4)]; - /// - /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip(); - /// - /// assert_eq!(left, [1, 3]); - /// assert_eq!(right, [2, 4]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn unzip(self) -> (FromA, FromB) where - FromA: Default + Extend, - FromB: Default + Extend, - Self: Sized + Iterator, - { - struct SizeHint(usize, Option, marker::PhantomData); - impl Iterator for SizeHint { - type Item = A; - - fn next(&mut self) -> Option { None } - fn size_hint(&self) -> (usize, Option) { - (self.0, self.1) - } - } - - let (lo, hi) = self.size_hint(); - let mut ts: FromA = Default::default(); - let mut us: FromB = Default::default(); - - ts.extend(SizeHint(lo, hi, marker::PhantomData)); - us.extend(SizeHint(lo, hi, marker::PhantomData)); - - for (t, u) in self { - ts.extend(Some(t)); - us.extend(Some(u)); - } - - (ts, us) - } - - /// Creates an iterator which `clone()`s all of its elements. - /// - /// This is useful when you have an iterator over `&T`, but you need an - /// iterator over `T`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let v_cloned: Vec<_> = a.iter().cloned().collect(); - /// - /// // cloned is the same as .map(|&x| x), for integers - /// let v_map: Vec<_> = a.iter().map(|&x| x).collect(); - /// - /// assert_eq!(v_cloned, vec![1, 2, 3]); - /// assert_eq!(v_map, vec![1, 2, 3]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn cloned<'a, T: 'a>(self) -> Cloned - where Self: Sized + Iterator, T: Clone - { - Cloned { it: self } - } - - /// Repeats an iterator endlessly. - /// - /// Instead of stopping at `None`, the iterator will instead start again, - /// from the beginning. After iterating again, it will start at the - /// beginning again. And again. And again. Forever. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let a = [1, 2, 3]; - /// - /// let mut it = a.iter().cycle(); - /// - /// assert_eq!(it.next(), Some(&1)); - /// assert_eq!(it.next(), Some(&2)); - /// assert_eq!(it.next(), Some(&3)); - /// assert_eq!(it.next(), Some(&1)); - /// assert_eq!(it.next(), Some(&2)); - /// assert_eq!(it.next(), Some(&3)); - /// assert_eq!(it.next(), Some(&1)); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - #[inline] - fn cycle(self) -> Cycle where Self: Sized + Clone { - Cycle{orig: self.clone(), iter: self} - } - - /// Sums the elements of an iterator. - /// - /// Takes each element, adds them together, and returns the result. - /// - /// An empty iterator returns the zero value of the type. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// #![feature(iter_arith)] - /// - /// let a = [1, 2, 3]; - /// let sum: i32 = a.iter().sum(); - /// - /// assert_eq!(sum, 6); - /// ``` - #[unstable(feature = "iter_arith", reason = "bounds recently changed", - issue = "27739")] - fn sum(self) -> S where - S: Add + Zero, - Self: Sized, - { - self.fold(Zero::zero(), |s, e| s + e) - } - - /// Iterates over the entire iterator, multiplying all the elements - /// - /// An empty iterator returns the one value of the type. - /// - /// # Examples - /// - /// ``` - /// #![feature(iter_arith)] - /// - /// fn factorial(n: u32) -> u32 { - /// (1..).take_while(|&i| i <= n).product() - /// } - /// assert_eq!(factorial(0), 1); - /// assert_eq!(factorial(1), 1); - /// assert_eq!(factorial(5), 120); - /// ``` - #[unstable(feature="iter_arith", reason = "bounds recently changed", - issue = "27739")] - fn product

(self) -> P where - P: Mul + One, - Self: Sized, - { - self.fold(One::one(), |p, e| p * e) - } - - /// Lexicographically compares the elements of this `Iterator` with those - /// of another. - #[stable(feature = "iter_order", since = "1.5.0")] - fn cmp(mut self, other: I) -> Ordering where - I: IntoIterator, - Self::Item: Ord, - Self: Sized, - { - let mut other = other.into_iter(); - - loop { - match (self.next(), other.next()) { - (None, None) => return Ordering::Equal, - (None, _ ) => return Ordering::Less, - (_ , None) => return Ordering::Greater, - (Some(x), Some(y)) => match x.cmp(&y) { - Ordering::Equal => (), - non_eq => return non_eq, - }, - } - } - } - - /// Lexicographically compares the elements of this `Iterator` with those - /// of another. - #[stable(feature = "iter_order", since = "1.5.0")] - fn partial_cmp(mut self, other: I) -> Option where - I: IntoIterator, - Self::Item: PartialOrd, - Self: Sized, - { - let mut other = other.into_iter(); - - loop { - match (self.next(), other.next()) { - (None, None) => return Some(Ordering::Equal), - (None, _ ) => return Some(Ordering::Less), - (_ , None) => return Some(Ordering::Greater), - (Some(x), Some(y)) => match x.partial_cmp(&y) { - Some(Ordering::Equal) => (), - non_eq => return non_eq, - }, - } - } - } - - /// Determines if the elements of this `Iterator` are equal to those of - /// another. - #[stable(feature = "iter_order", since = "1.5.0")] - fn eq(mut self, other: I) -> bool where - I: IntoIterator, - Self::Item: PartialEq, - Self: Sized, - { - let mut other = other.into_iter(); - - loop { - match (self.next(), other.next()) { - (None, None) => return true, - (None, _) | (_, None) => return false, - (Some(x), Some(y)) => if x != y { return false }, - } - } - } - - /// Determines if the elements of this `Iterator` are unequal to those of - /// another. - #[stable(feature = "iter_order", since = "1.5.0")] - fn ne(mut self, other: I) -> bool where - I: IntoIterator, - Self::Item: PartialEq, - Self: Sized, - { - let mut other = other.into_iter(); - - loop { - match (self.next(), other.next()) { - (None, None) => return false, - (None, _) | (_, None) => return true, - (Some(x), Some(y)) => if x.ne(&y) { return true }, - } - } - } - - /// Determines if the elements of this `Iterator` are lexicographically - /// less than those of another. - #[stable(feature = "iter_order", since = "1.5.0")] - fn lt(mut self, other: I) -> bool where - I: IntoIterator, - Self::Item: PartialOrd, - Self: Sized, - { - let mut other = other.into_iter(); - - loop { - match (self.next(), other.next()) { - (None, None) => return false, - (None, _ ) => return true, - (_ , None) => return false, - (Some(x), Some(y)) => { - match x.partial_cmp(&y) { - Some(Ordering::Less) => return true, - Some(Ordering::Equal) => {} - Some(Ordering::Greater) => return false, - None => return false, - } - }, - } - } - } - - /// Determines if the elements of this `Iterator` are lexicographically - /// less or equal to those of another. - #[stable(feature = "iter_order", since = "1.5.0")] - fn le(mut self, other: I) -> bool where - I: IntoIterator, - Self::Item: PartialOrd, - Self: Sized, - { - let mut other = other.into_iter(); - - loop { - match (self.next(), other.next()) { - (None, None) => return true, - (None, _ ) => return true, - (_ , None) => return false, - (Some(x), Some(y)) => { - match x.partial_cmp(&y) { - Some(Ordering::Less) => return true, - Some(Ordering::Equal) => {} - Some(Ordering::Greater) => return false, - None => return false, - } - }, - } - } - } - - /// Determines if the elements of this `Iterator` are lexicographically - /// greater than those of another. - #[stable(feature = "iter_order", since = "1.5.0")] - fn gt(mut self, other: I) -> bool where - I: IntoIterator, - Self::Item: PartialOrd, - Self: Sized, - { - let mut other = other.into_iter(); - - loop { - match (self.next(), other.next()) { - (None, None) => return false, - (None, _ ) => return false, - (_ , None) => return true, - (Some(x), Some(y)) => { - match x.partial_cmp(&y) { - Some(Ordering::Less) => return false, - Some(Ordering::Equal) => {} - Some(Ordering::Greater) => return true, - None => return false, - } - } - } - } - } - - /// Determines if the elements of this `Iterator` are lexicographically - /// greater than or equal to those of another. - #[stable(feature = "iter_order", since = "1.5.0")] - fn ge(mut self, other: I) -> bool where - I: IntoIterator, - Self::Item: PartialOrd, - Self: Sized, - { - let mut other = other.into_iter(); - - loop { - match (self.next(), other.next()) { - (None, None) => return true, - (None, _ ) => return false, - (_ , None) => return true, - (Some(x), Some(y)) => { - match x.partial_cmp(&y) { - Some(Ordering::Less) => return false, - Some(Ordering::Equal) => {} - Some(Ordering::Greater) => return true, - None => return false, - } - }, - } - } - } -} - -/// Select an element from an iterator based on the given projection -/// and "comparison" function. -/// -/// This is an idiosyncratic helper to try to factor out the -/// commonalities of {max,min}{,_by}. In particular, this avoids -/// having to implement optimizations several times. -#[inline] -fn select_fold1(mut it: I, - mut f_proj: FProj, - mut f_cmp: FCmp) -> Option<(B, I::Item)> - where I: Iterator, - FProj: FnMut(&I::Item) -> B, - FCmp: FnMut(&B, &I::Item, &B, &I::Item) -> bool -{ - // start with the first element as our selection. This avoids - // having to use `Option`s inside the loop, translating to a - // sizeable performance gain (6x in one case). - it.next().map(|mut sel| { - let mut sel_p = f_proj(&sel); - - for x in it { - let x_p = f_proj(&x); - if f_cmp(&sel_p, &sel, &x_p, &x) { - sel = x; - sel_p = x_p; - } - } - (sel_p, sel) - }) -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I { - type Item = I::Item; - fn next(&mut self) -> Option { (**self).next() } - fn size_hint(&self) -> (usize, Option) { (**self).size_hint() } -} - -/// Conversion from an `Iterator`. -/// -/// By implementing `FromIterator` for a type, you define how it will be -/// created from an iterator. This is common for types which describe a -/// collection of some kind. -/// -/// `FromIterator`'s [`from_iter()`] is rarely called explicitly, and is instead -/// used through [`Iterator`]'s [`collect()`] method. See [`collect()`]'s -/// documentation for more examples. -/// -/// [`from_iter()`]: #tymethod.from_iter -/// [`Iterator`]: trait.Iterator.html -/// [`collect()`]: trait.Iterator.html#method.collect -/// -/// See also: [`IntoIterator`]. -/// -/// [`IntoIterator`]: trait.IntoIterator.html -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// use std::iter::FromIterator; -/// -/// let five_fives = std::iter::repeat(5).take(5); -/// -/// let v = Vec::from_iter(five_fives); -/// -/// assert_eq!(v, vec![5, 5, 5, 5, 5]); -/// ``` -/// -/// Using [`collect()`] to implicitly use `FromIterator`: -/// -/// ``` -/// let five_fives = std::iter::repeat(5).take(5); -/// -/// let v: Vec = five_fives.collect(); -/// -/// assert_eq!(v, vec![5, 5, 5, 5, 5]); -/// ``` -/// -/// Implementing `FromIterator` for your type: -/// -/// ``` -/// use std::iter::FromIterator; -/// -/// // A sample collection, that's just a wrapper over Vec -/// #[derive(Debug)] -/// struct MyCollection(Vec); -/// -/// // Let's give it some methods so we can create one and add things -/// // to it. -/// impl MyCollection { -/// fn new() -> MyCollection { -/// MyCollection(Vec::new()) -/// } -/// -/// fn add(&mut self, elem: i32) { -/// self.0.push(elem); -/// } -/// } -/// -/// // and we'll implement FromIterator -/// impl FromIterator for MyCollection { -/// fn from_iter>(iter: I) -> Self { -/// let mut c = MyCollection::new(); -/// -/// for i in iter { -/// c.add(i); -/// } -/// -/// c -/// } -/// } -/// -/// // Now we can make a new iterator... -/// let iter = (0..5).into_iter(); -/// -/// // ... and make a MyCollection out of it -/// let c = MyCollection::from_iter(iter); -/// -/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); -/// -/// // collect works too! -/// -/// let iter = (0..5).into_iter(); -/// let c: MyCollection = iter.collect(); -/// -/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ - built from an iterator over elements of type `{A}`"] -pub trait FromIterator: Sized { - /// Creates a value from an iterator. - /// - /// See the [module-level documentation] for more. - /// - /// [module-level documentation]: trait.FromIterator.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// use std::iter::FromIterator; - /// - /// let five_fives = std::iter::repeat(5).take(5); - /// - /// let v = Vec::from_iter(five_fives); - /// - /// assert_eq!(v, vec![5, 5, 5, 5, 5]); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn from_iter>(iter: T) -> Self; -} - -/// Conversion into an `Iterator`. -/// -/// By implementing `IntoIterator` for a type, you define how it will be -/// converted to an iterator. This is common for types which describe a -/// collection of some kind. -/// -/// One benefit of implementing `IntoIterator` is that your type will [work -/// with Rust's `for` loop syntax](index.html#for-loops-and-intoiterator). -/// -/// See also: [`FromIterator`]. -/// -/// [`FromIterator`]: trait.FromIterator.html -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// let v = vec![1, 2, 3]; -/// -/// let mut iter = v.into_iter(); -/// -/// let n = iter.next(); -/// assert_eq!(Some(1), n); -/// -/// let n = iter.next(); -/// assert_eq!(Some(2), n); -/// -/// let n = iter.next(); -/// assert_eq!(Some(3), n); -/// -/// let n = iter.next(); -/// assert_eq!(None, n); -/// ``` -/// -/// Implementing `IntoIterator` for your type: -/// -/// ``` -/// // A sample collection, that's just a wrapper over Vec -/// #[derive(Debug)] -/// struct MyCollection(Vec); -/// -/// // Let's give it some methods so we can create one and add things -/// // to it. -/// impl MyCollection { -/// fn new() -> MyCollection { -/// MyCollection(Vec::new()) -/// } -/// -/// fn add(&mut self, elem: i32) { -/// self.0.push(elem); -/// } -/// } -/// -/// // and we'll implement IntoIterator -/// impl IntoIterator for MyCollection { -/// type Item = i32; -/// type IntoIter = ::std::vec::IntoIter; -/// -/// fn into_iter(self) -> Self::IntoIter { -/// self.0.into_iter() -/// } -/// } -/// -/// // Now we can make a new collection... -/// let mut c = MyCollection::new(); -/// -/// // ... add some stuff to it ... -/// c.add(0); -/// c.add(1); -/// c.add(2); -/// -/// // ... and then turn it into an Iterator: -/// for (i, n) in c.into_iter().enumerate() { -/// assert_eq!(i as i32, n); -/// } -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub trait IntoIterator { - /// The type of the elements being iterated over. - #[stable(feature = "rust1", since = "1.0.0")] - type Item; - - /// Which kind of iterator are we turning this into? - #[stable(feature = "rust1", since = "1.0.0")] - type IntoIter: Iterator; - - /// Creates an iterator from a value. - /// - /// See the [module-level documentation] for more. - /// - /// [module-level documentation]: trait.IntoIterator.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let v = vec![1, 2, 3]; - /// - /// let mut iter = v.into_iter(); - /// - /// let n = iter.next(); - /// assert_eq!(Some(1), n); - /// - /// let n = iter.next(); - /// assert_eq!(Some(2), n); - /// - /// let n = iter.next(); - /// assert_eq!(Some(3), n); - /// - /// let n = iter.next(); - /// assert_eq!(None, n); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn into_iter(self) -> Self::IntoIter; -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl IntoIterator for I { - type Item = I::Item; - type IntoIter = I; - - fn into_iter(self) -> I { - self - } -} - -/// Extend a collection with the contents of an iterator. -/// -/// Iterators produce a series of values, and collections can also be thought -/// of as a series of values. The `Extend` trait bridges this gap, allowing you -/// to extend a collection by including the contents of that iterator. -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// // You can extend a String with some chars: -/// let mut message = String::from("The first three letters are: "); -/// -/// message.extend(&['a', 'b', 'c']); -/// -/// assert_eq!("abc", &message[29..32]); -/// ``` -/// -/// Implementing `Extend`: -/// -/// ``` -/// // A sample collection, that's just a wrapper over Vec -/// #[derive(Debug)] -/// struct MyCollection(Vec); -/// -/// // Let's give it some methods so we can create one and add things -/// // to it. -/// impl MyCollection { -/// fn new() -> MyCollection { -/// MyCollection(Vec::new()) -/// } -/// -/// fn add(&mut self, elem: i32) { -/// self.0.push(elem); -/// } -/// } -/// -/// // since MyCollection has a list of i32s, we implement Extend for i32 -/// impl Extend for MyCollection { -/// -/// // This is a bit simpler with the concrete type signature: we can call -/// // extend on anything which can be turned into an Iterator which gives -/// // us i32s. Because we need i32s to put into MyCollection. -/// fn extend>(&mut self, iter: T) { -/// -/// // The implementation is very straightforward: loop through the -/// // iterator, and add() each element to ourselves. -/// for elem in iter { -/// self.add(elem); -/// } -/// } -/// } -/// -/// let mut c = MyCollection::new(); -/// -/// c.add(5); -/// c.add(6); -/// c.add(7); -/// -/// // let's extend our collection with three more numbers -/// c.extend(vec![1, 2, 3]); -/// -/// // we've added these elements onto the end -/// assert_eq!("MyCollection([5, 6, 7, 1, 2, 3])", format!("{:?}", c)); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub trait Extend { - /// Extends a collection with the contents of an iterator. - /// - /// As this is the only method for this trait, the [trait-level] docs - /// contain more details. - /// - /// [trait-level]: trait.Extend.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// // You can extend a String with some chars: - /// let mut message = String::from("abc"); - /// - /// message.extend(['d', 'e', 'f'].iter()); - /// - /// assert_eq!("abcdef", &message); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn extend>(&mut self, iter: T); -} - -/// An iterator able to yield elements from both ends. -/// -/// Something that implements `DoubleEndedIterator` has one extra capability -/// over something that implements [`Iterator`]: the ability to also take -/// `Item`s from the back, as well as the front. -/// -/// It is important to note that both back and forth work on the same range, -/// and do not cross: iteration is over when they meet in the middle. -/// -/// In a similar fashion to the [`Iterator`] protocol, once a -/// `DoubleEndedIterator` returns `None` from a `next_back()`, calling it again -/// may or may not ever return `Some` again. `next()` and `next_back()` are -/// interchangable for this purpose. -/// -/// [`Iterator`]: trait.Iterator.html -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// let numbers = vec![1, 2, 3]; -/// -/// let mut iter = numbers.iter(); -/// -/// assert_eq!(Some(&1), iter.next()); -/// assert_eq!(Some(&3), iter.next_back()); -/// assert_eq!(Some(&2), iter.next_back()); -/// assert_eq!(None, iter.next()); -/// assert_eq!(None, iter.next_back()); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub trait DoubleEndedIterator: Iterator { - /// An iterator able to yield elements from both ends. - /// - /// As this is the only method for this trait, the [trait-level] docs - /// contain more details. - /// - /// [trait-level]: trait.DoubleEndedIterator.html - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let numbers = vec![1, 2, 3]; - /// - /// let mut iter = numbers.iter(); - /// - /// assert_eq!(Some(&1), iter.next()); - /// assert_eq!(Some(&3), iter.next_back()); - /// assert_eq!(Some(&2), iter.next_back()); - /// assert_eq!(None, iter.next()); - /// assert_eq!(None, iter.next_back()); - /// ``` - #[stable(feature = "rust1", since = "1.0.0")] - fn next_back(&mut self) -> Option; -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { - fn next_back(&mut self) -> Option { (**self).next_back() } -} - -/// An iterator that knows its exact length. -/// -/// Many [`Iterator`]s don't know how many times they will iterate, but some do. -/// If an iterator knows how many times it can iterate, providing access to -/// that information can be useful. For example, if you want to iterate -/// backwards, a good start is to know where the end is. -/// -/// When implementing an `ExactSizeIterator`, You must also implement -/// [`Iterator`]. When doing so, the implementation of [`size_hint()`] *must* -/// return the exact size of the iterator. -/// -/// [`Iterator`]: trait.Iterator.html -/// [`size_hint()`]: trait.Iterator.html#method.size_hint -/// -/// The [`len()`] method has a default implementation, so you usually shouldn't -/// implement it. However, you may be able to provide a more performant -/// implementation than the default, so overriding it in this case makes sense. -/// -/// [`len()`]: #method.len -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// // a finite range knows exactly how many times it will iterate -/// let five = 0..5; -/// -/// assert_eq!(5, five.len()); -/// ``` -/// -/// In the [module level docs][moddocs], we implemented an [`Iterator`], -/// `Counter`. Let's implement `ExactSizeIterator` for it as well: -/// -/// [moddocs]: index.html -/// -/// ``` -/// # struct Counter { -/// # count: usize, -/// # } -/// # impl Counter { -/// # fn new() -> Counter { -/// # Counter { count: 0 } -/// # } -/// # } -/// # impl Iterator for Counter { -/// # type Item = usize; -/// # fn next(&mut self) -> Option { -/// # self.count += 1; -/// # if self.count < 6 { -/// # Some(self.count) -/// # } else { -/// # None -/// # } -/// # } -/// # } -/// impl ExactSizeIterator for Counter { -/// // We already have the number of iterations, so we can use it directly. -/// fn len(&self) -> usize { -/// self.count -/// } -/// } -/// -/// // And now we can use it! -/// -/// let counter = Counter::new(); -/// -/// assert_eq!(0, counter.len()); -/// ``` -#[stable(feature = "rust1", since = "1.0.0")] -pub trait ExactSizeIterator: Iterator { - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - /// Returns the exact number of times the iterator will iterate. - /// - /// This method has a default implementation, so you usually should not - /// implement it directly. However, if you can provide a more efficient - /// implementation, you can do so. See the [trait-level] docs for an - /// example. - /// - /// This function has the same safety guarantees as the [`size_hint()`] - /// function. - /// - /// [trait-level]: trait.ExactSizeIterator.html - /// [`size_hint()`]: trait.Iterator.html#method.size_hint - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// // a finite range knows exactly how many times it will iterate - /// let five = 0..5; - /// - /// assert_eq!(5, five.len()); - /// ``` - fn len(&self) -> usize { - let (lower, upper) = self.size_hint(); - // Note: This assertion is overly defensive, but it checks the invariant - // guaranteed by the trait. If this trait were rust-internal, - // we could use debug_assert!; assert_eq! will check all Rust user - // implementations too. - assert_eq!(upper, Some(lower)); - lower - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I {} - -// All adaptors that preserve the size of the wrapped iterator are fine -// Adaptors that may overflow in `size_hint` are not, i.e. `Chain`. -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Enumerate where I: ExactSizeIterator {} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Inspect where - F: FnMut(&I::Item), -{} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Rev - where I: ExactSizeIterator + DoubleEndedIterator {} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Map where - F: FnMut(I::Item) -> B, -{} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Zip - where A: ExactSizeIterator, B: ExactSizeIterator {} - -/// An double-ended iterator with the direction inverted. -/// -/// This `struct` is created by the [`rev()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`rev()`]: trait.Iterator.html#method.rev -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Rev { - iter: T -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Rev where I: DoubleEndedIterator { - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option<::Item> { self.iter.next_back() } - #[inline] - fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Rev where I: DoubleEndedIterator { - #[inline] - fn next_back(&mut self) -> Option<::Item> { self.iter.next() } -} - -/// An iterator that clones the elements of an underlying iterator. -/// -/// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`cloned()`]: trait.Iterator.html#method.cloned -/// [`Iterator`]: trait.Iterator.html -#[stable(feature = "iter_cloned", since = "1.1.0")] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[derive(Clone, Debug)] -pub struct Cloned { - it: I, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, I, T: 'a> Iterator for Cloned - where I: Iterator, T: Clone -{ - type Item = T; - - fn next(&mut self) -> Option { - self.it.next().cloned() - } - - fn size_hint(&self) -> (usize, Option) { - self.it.size_hint() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, I, T: 'a> DoubleEndedIterator for Cloned - where I: DoubleEndedIterator, T: Clone -{ - fn next_back(&mut self) -> Option { - self.it.next_back().cloned() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl<'a, I, T: 'a> ExactSizeIterator for Cloned - where I: ExactSizeIterator, T: Clone -{} - -/// An iterator that repeats endlessly. -/// -/// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`cycle()`]: trait.Iterator.html#method.cycle -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Cycle { - orig: I, - iter: I, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Cycle where I: Clone + Iterator { - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option<::Item> { - match self.iter.next() { - None => { self.iter = self.orig.clone(); self.iter.next() } - y => y - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - // the cycle iterator is either empty or infinite - match self.orig.size_hint() { - sz @ (0, Some(0)) => sz, - (0, _) => (0, None), - _ => (usize::MAX, None) - } - } -} - -/// An iterator that strings two iterators together. -/// -/// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`chain()`]: trait.Iterator.html#method.chain -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Chain { - a: A, - b: B, - state: ChainState, -} - -// The iterator protocol specifies that iteration ends with the return value -// `None` from `.next()` (or `.next_back()`) and it is unspecified what -// further calls return. The chain adaptor must account for this since it uses -// two subiterators. -// -// It uses three states: -// -// - Both: `a` and `b` are remaining -// - Front: `a` remaining -// - Back: `b` remaining -// -// The fourth state (neither iterator is remaining) only occurs after Chain has -// returned None once, so we don't need to store this state. -#[derive(Clone, Debug)] -enum ChainState { - // both front and back iterator are remaining - Both, - // only front is remaining - Front, - // only back is remaining - Back, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Chain where - A: Iterator, - B: Iterator -{ - type Item = A::Item; - - #[inline] - fn next(&mut self) -> Option { - match self.state { - ChainState::Both => match self.a.next() { - elt @ Some(..) => elt, - None => { - self.state = ChainState::Back; - self.b.next() - } - }, - ChainState::Front => self.a.next(), - ChainState::Back => self.b.next(), - } - } - - #[inline] - fn count(self) -> usize { - match self.state { - ChainState::Both => self.a.count() + self.b.count(), - ChainState::Front => self.a.count(), - ChainState::Back => self.b.count(), - } - } - - #[inline] - fn nth(&mut self, mut n: usize) -> Option { - match self.state { - ChainState::Both | ChainState::Front => { - for x in self.a.by_ref() { - if n == 0 { - return Some(x) - } - n -= 1; - } - if let ChainState::Both = self.state { - self.state = ChainState::Back; - } - } - ChainState::Back => {} - } - if let ChainState::Back = self.state { - self.b.nth(n) - } else { - None - } - } - - #[inline] - fn last(self) -> Option { - match self.state { - ChainState::Both => { - // Must exhaust a before b. - let a_last = self.a.last(); - let b_last = self.b.last(); - b_last.or(a_last) - }, - ChainState::Front => self.a.last(), - ChainState::Back => self.b.last() - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (a_lower, a_upper) = self.a.size_hint(); - let (b_lower, b_upper) = self.b.size_hint(); - - let lower = a_lower.saturating_add(b_lower); - - let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => x.checked_add(y), - _ => None - }; - - (lower, upper) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Chain where - A: DoubleEndedIterator, - B: DoubleEndedIterator, -{ - #[inline] - fn next_back(&mut self) -> Option { - match self.state { - ChainState::Both => match self.b.next_back() { - elt @ Some(..) => elt, - None => { - self.state = ChainState::Front; - self.a.next_back() - } - }, - ChainState::Front => self.a.next_back(), - ChainState::Back => self.b.next_back(), - } - } -} - -/// An iterator that iterates two other iterators simultaneously. -/// -/// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`zip()`]: trait.Iterator.html#method.zip -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Zip { - a: A, - b: B -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Zip where A: Iterator, B: Iterator -{ - type Item = (A::Item, B::Item); - - #[inline] - fn next(&mut self) -> Option<(A::Item, B::Item)> { - self.a.next().and_then(|x| { - self.b.next().and_then(|y| { - Some((x, y)) - }) - }) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (a_lower, a_upper) = self.a.size_hint(); - let (b_lower, b_upper) = self.b.size_hint(); - - let lower = cmp::min(a_lower, b_lower); - - let upper = match (a_upper, b_upper) { - (Some(x), Some(y)) => Some(cmp::min(x,y)), - (Some(x), None) => Some(x), - (None, Some(y)) => Some(y), - (None, None) => None - }; - - (lower, upper) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Zip where - A: DoubleEndedIterator + ExactSizeIterator, - B: DoubleEndedIterator + ExactSizeIterator, -{ - #[inline] - fn next_back(&mut self) -> Option<(A::Item, B::Item)> { - let a_sz = self.a.len(); - let b_sz = self.b.len(); - if a_sz != b_sz { - // Adjust a, b to equal length - if a_sz > b_sz { - for _ in 0..a_sz - b_sz { self.a.next_back(); } - } else { - for _ in 0..b_sz - a_sz { self.b.next_back(); } - } - } - match (self.a.next_back(), self.b.next_back()) { - (Some(x), Some(y)) => Some((x, y)), - (None, None) => None, - _ => unreachable!(), - } - } -} - -/// An iterator that maps the values of `iter` with `f`. -/// -/// This `struct` is created by the [`map()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`map()`]: trait.Iterator.html#method.map -/// [`Iterator`]: trait.Iterator.html -/// -/// # Notes about side effects -/// -/// The [`map()`] iterator implements [`DoubleEndedIterator`], meaning that -/// you can also [`map()`] backwards: -/// -/// ```rust -/// let v: Vec = vec![1, 2, 3].into_iter().rev().map(|x| x + 1).collect(); -/// -/// assert_eq!(v, [4, 3, 2]); -/// ``` -/// -/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html -/// -/// But if your closure has state, iterating backwards may act in a way you do -/// not expect. Let's go through an example. First, in the forward direction: -/// -/// ```rust -/// let mut c = 0; -/// -/// for pair in vec!['a', 'b', 'c'].into_iter() -/// .map(|letter| { c += 1; (letter, c) }) { -/// println!("{:?}", pair); -/// } -/// ``` -/// -/// This will print "('a', 1), ('b', 2), ('c', 3)". -/// -/// Now consider this twist where we add a call to `rev`. This version will -/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed, -/// but the values of the counter still go in order. This is because `map()` is -/// still being called lazilly on each item, but we are popping items off the -/// back of the vector now, instead of shifting them from the front. -/// -/// ```rust -/// let mut c = 0; -/// -/// for pair in vec!['a', 'b', 'c'].into_iter() -/// .map(|letter| { c += 1; (letter, c) }) -/// .rev() { -/// println!("{:?}", pair); -/// } -/// ``` -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct Map { - iter: I, - f: F, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Map { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Map") - .field("iter", &self.iter) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Map where F: FnMut(I::Item) -> B { - type Item = B; - - #[inline] - fn next(&mut self) -> Option { - self.iter.next().map(&mut self.f) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Map where - F: FnMut(I::Item) -> B, -{ - #[inline] - fn next_back(&mut self) -> Option { - self.iter.next_back().map(&mut self.f) - } -} - -/// An iterator that filters the elements of `iter` with `predicate`. -/// -/// This `struct` is created by the [`filter()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`filter()`]: trait.Iterator.html#method.filter -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct Filter { - iter: I, - predicate: P, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Filter { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Filter") - .field("iter", &self.iter) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Filter where P: FnMut(&I::Item) -> bool { - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - for x in self.iter.by_ref() { - if (self.predicate)(&x) { - return Some(x); - } - } - None - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Filter - where P: FnMut(&I::Item) -> bool, -{ - #[inline] - fn next_back(&mut self) -> Option { - for x in self.iter.by_ref().rev() { - if (self.predicate)(&x) { - return Some(x); - } - } - None - } -} - -/// An iterator that uses `f` to both filter and map elements from `iter`. -/// -/// This `struct` is created by the [`filter_map()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`filter_map()`]: trait.Iterator.html#method.filter_map -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct FilterMap { - iter: I, - f: F, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for FilterMap { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("FilterMap") - .field("iter", &self.iter) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for FilterMap - where F: FnMut(I::Item) -> Option, -{ - type Item = B; - - #[inline] - fn next(&mut self) -> Option { - for x in self.iter.by_ref() { - if let Some(y) = (self.f)(x) { - return Some(y); - } - } - None - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for FilterMap - where F: FnMut(I::Item) -> Option, -{ - #[inline] - fn next_back(&mut self) -> Option { - for x in self.iter.by_ref().rev() { - if let Some(y) = (self.f)(x) { - return Some(y); - } - } - None - } -} - -/// An iterator that yields the current count and the element during iteration. -/// -/// This `struct` is created by the [`enumerate()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`enumerate()`]: trait.Iterator.html#method.enumerate -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Enumerate { - iter: I, - count: usize, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Enumerate where I: Iterator { - type Item = (usize, ::Item); - - /// # Overflow Behavior - /// - /// The method does no guarding against overflows, so enumerating more than - /// `usize::MAX` elements either produces the wrong result or panics. If - /// debug assertions are enabled, a panic is guaranteed. - /// - /// # Panics - /// - /// Might panic if the index of the element overflows a `usize`. - #[inline] - fn next(&mut self) -> Option<(usize, ::Item)> { - self.iter.next().map(|a| { - let ret = (self.count, a); - // Possible undefined overflow. - self.count += 1; - ret - }) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } - - #[inline] - fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> { - self.iter.nth(n).map(|a| { - let i = self.count + n; - self.count = i + 1; - (i, a) - }) - } - - #[inline] - fn count(self) -> usize { - self.iter.count() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Enumerate where - I: ExactSizeIterator + DoubleEndedIterator -{ - #[inline] - fn next_back(&mut self) -> Option<(usize, ::Item)> { - self.iter.next_back().map(|a| { - let len = self.iter.len(); - // Can safely add, `ExactSizeIterator` promises that the number of - // elements fits into a `usize`. - (self.count + len, a) - }) - } -} - -/// An iterator with a `peek()` that returns an optional reference to the next -/// element. -/// -/// This `struct` is created by the [`peekable()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`peekable()`]: trait.Iterator.html#method.peekable -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Peekable { - iter: I, - peeked: Option, -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Peekable { - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - match self.peeked { - Some(_) => self.peeked.take(), - None => self.iter.next(), - } - } - - #[inline] - fn count(self) -> usize { - (if self.peeked.is_some() { 1 } else { 0 }) + self.iter.count() - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - match self.peeked { - Some(_) if n == 0 => self.peeked.take(), - Some(_) => { - self.peeked = None; - self.iter.nth(n-1) - }, - None => self.iter.nth(n) - } - } - - #[inline] - fn last(self) -> Option { - self.iter.last().or(self.peeked) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (lo, hi) = self.iter.size_hint(); - if self.peeked.is_some() { - let lo = lo.saturating_add(1); - let hi = hi.and_then(|x| x.checked_add(1)); - (lo, hi) - } else { - (lo, hi) - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Peekable {} - -impl Peekable { - /// Returns a reference to the next() value without advancing the iterator. - /// - /// The `peek()` method will return the value that a call to [`next()`] would - /// return, but does not advance the iterator. Like [`next()`], if there is - /// a value, it's wrapped in a `Some(T)`, but if the iterator is over, it - /// will return `None`. - /// - /// [`next()`]: trait.Iterator.html#tymethod.next - /// - /// Because `peek()` returns reference, and many iterators iterate over - /// references, this leads to a possibly confusing situation where the - /// return value is a double reference. You can see this effect in the - /// examples below, with `&&i32`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let xs = [1, 2, 3]; - /// - /// let mut iter = xs.iter().peekable(); - /// - /// // peek() lets us see into the future - /// assert_eq!(iter.peek(), Some(&&1)); - /// assert_eq!(iter.next(), Some(&1)); - /// - /// assert_eq!(iter.next(), Some(&2)); - /// - /// // we can peek() multiple times, the iterator won't advance - /// assert_eq!(iter.peek(), Some(&&3)); - /// assert_eq!(iter.peek(), Some(&&3)); - /// - /// assert_eq!(iter.next(), Some(&3)); - /// - /// // after the iterator is finished, so is peek() - /// assert_eq!(iter.peek(), None); - /// assert_eq!(iter.next(), None); - /// ``` - #[inline] - #[stable(feature = "rust1", since = "1.0.0")] - pub fn peek(&mut self) -> Option<&I::Item> { - if self.peeked.is_none() { - self.peeked = self.iter.next(); - } - match self.peeked { - Some(ref value) => Some(value), - None => None, - } - } - - /// Checks if the iterator has finished iterating. - /// - /// Returns `true` if there are no more elements in the iterator, and - /// `false` if there are. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// #![feature(peekable_is_empty)] - /// - /// let xs = [1, 2, 3]; - /// - /// let mut iter = xs.iter().peekable(); - /// - /// // there are still elements to iterate over - /// assert_eq!(iter.is_empty(), false); - /// - /// // let's consume the iterator - /// iter.next(); - /// iter.next(); - /// iter.next(); - /// - /// assert_eq!(iter.is_empty(), true); - /// ``` - #[unstable(feature = "peekable_is_empty", issue = "32111")] - #[inline] - pub fn is_empty(&mut self) -> bool { - self.peek().is_none() - } -} - -/// An iterator that rejects elements while `predicate` is true. -/// -/// This `struct` is created by the [`skip_while()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`skip_while()`]: trait.Iterator.html#method.skip_while -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct SkipWhile { - iter: I, - flag: bool, - predicate: P, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for SkipWhile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("SkipWhile") - .field("iter", &self.iter) - .field("flag", &self.flag) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for SkipWhile - where P: FnMut(&I::Item) -> bool -{ - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - for x in self.iter.by_ref() { - if self.flag || !(self.predicate)(&x) { - self.flag = true; - return Some(x); - } - } - None - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } -} - -/// An iterator that only accepts elements while `predicate` is true. -/// -/// This `struct` is created by the [`take_while()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`take_while()`]: trait.Iterator.html#method.take_while -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct TakeWhile { - iter: I, - flag: bool, - predicate: P, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for TakeWhile { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("TakeWhile") - .field("iter", &self.iter) - .field("flag", &self.flag) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for TakeWhile - where P: FnMut(&I::Item) -> bool -{ - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - if self.flag { - None - } else { - self.iter.next().and_then(|x| { - if (self.predicate)(&x) { - Some(x) - } else { - self.flag = true; - None - } - }) - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the predicate - } -} - -/// An iterator that skips over `n` elements of `iter`. -/// -/// This `struct` is created by the [`skip()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`skip()`]: trait.Iterator.html#method.skip -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Skip { - iter: I, - n: usize -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Skip where I: Iterator { - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option { - if self.n == 0 { - self.iter.next() - } else { - let old_n = self.n; - self.n = 0; - self.iter.nth(old_n) - } - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - // Can't just add n + self.n due to overflow. - if self.n == 0 { - self.iter.nth(n) - } else { - let to_skip = self.n; - self.n = 0; - // nth(n) skips n+1 - if self.iter.nth(to_skip-1).is_none() { - return None; - } - self.iter.nth(n) - } - } - - #[inline] - fn count(self) -> usize { - self.iter.count().saturating_sub(self.n) - } - - #[inline] - fn last(mut self) -> Option { - if self.n == 0 { - self.iter.last() - } else { - let next = self.next(); - if next.is_some() { - // recurse. n should be 0. - self.last().or(next) - } else { - None - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (lower, upper) = self.iter.size_hint(); - - let lower = lower.saturating_sub(self.n); - let upper = upper.map(|x| x.saturating_sub(self.n)); - - (lower, upper) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Skip where I: ExactSizeIterator {} - -#[stable(feature = "double_ended_skip_iterator", since = "1.8.0")] -impl DoubleEndedIterator for Skip where I: DoubleEndedIterator + ExactSizeIterator { - fn next_back(&mut self) -> Option { - if self.len() > 0 { - self.iter.next_back() - } else { - None - } - } -} - -/// An iterator that only iterates over the first `n` iterations of `iter`. -/// -/// This `struct` is created by the [`take()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`take()`]: trait.Iterator.html#method.take -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Take { - iter: I, - n: usize -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Take where I: Iterator{ - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option<::Item> { - if self.n != 0 { - self.n -= 1; - self.iter.next() - } else { - None - } - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - if self.n > n { - self.n -= n + 1; - self.iter.nth(n) - } else { - if self.n > 0 { - self.iter.nth(self.n - 1); - self.n = 0; - } - None - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (lower, upper) = self.iter.size_hint(); - - let lower = cmp::min(lower, self.n); - - let upper = match upper { - Some(x) if x < self.n => Some(x), - _ => Some(self.n) - }; - - (lower, upper) - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Take where I: ExactSizeIterator {} - - -/// An iterator to maintain state while iterating another iterator. -/// -/// This `struct` is created by the [`scan()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`scan()`]: trait.Iterator.html#method.scan -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct Scan { - iter: I, - f: F, - state: St, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Scan { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Scan") - .field("iter", &self.iter) - .field("state", &self.state) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Scan where - I: Iterator, - F: FnMut(&mut St, I::Item) -> Option, -{ - type Item = B; - - #[inline] - fn next(&mut self) -> Option { - self.iter.next().and_then(|a| (self.f)(&mut self.state, a)) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (_, upper) = self.iter.size_hint(); - (0, upper) // can't know a lower bound, due to the scan function - } -} - -/// An iterator that maps each element to an iterator, and yields the elements -/// of the produced iterators. -/// -/// This `struct` is created by the [`flat_map()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`flat_map()`]: trait.Iterator.html#method.flat_map -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct FlatMap { - iter: I, - f: F, - frontiter: Option, - backiter: Option, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for FlatMap - where U::IntoIter: fmt::Debug -{ - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("FlatMap") - .field("iter", &self.iter) - .field("frontiter", &self.frontiter) - .field("backiter", &self.backiter) - .finish() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for FlatMap - where F: FnMut(I::Item) -> U, -{ - type Item = U::Item; - - #[inline] - fn next(&mut self) -> Option { - loop { - if let Some(ref mut inner) = self.frontiter { - if let Some(x) = inner.by_ref().next() { - return Some(x) - } - } - match self.iter.next().map(&mut self.f) { - None => return self.backiter.as_mut().and_then(|it| it.next()), - next => self.frontiter = next.map(IntoIterator::into_iter), - } - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); - let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); - let lo = flo.saturating_add(blo); - match (self.iter.size_hint(), fhi, bhi) { - ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)), - _ => (lo, None) - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for FlatMap where - F: FnMut(I::Item) -> U, - U: IntoIterator, - U::IntoIter: DoubleEndedIterator -{ - #[inline] - fn next_back(&mut self) -> Option { - loop { - if let Some(ref mut inner) = self.backiter { - if let Some(y) = inner.next_back() { - return Some(y) - } - } - match self.iter.next_back().map(&mut self.f) { - None => return self.frontiter.as_mut().and_then(|it| it.next_back()), - next => self.backiter = next.map(IntoIterator::into_iter), - } - } - } -} - -/// An iterator that yields `None` forever after the underlying iterator -/// yields `None` once. -/// -/// This `struct` is created by the [`fuse()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`fuse()`]: trait.Iterator.html#method.fuse -/// [`Iterator`]: trait.Iterator.html -#[derive(Clone, Debug)] -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Fuse { - iter: I, - done: bool -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Fuse where I: Iterator { - type Item = ::Item; - - #[inline] - fn next(&mut self) -> Option<::Item> { - if self.done { - None - } else { - let next = self.iter.next(); - self.done = next.is_none(); - next - } - } - - #[inline] - fn nth(&mut self, n: usize) -> Option { - if self.done { - None - } else { - let nth = self.iter.nth(n); - self.done = nth.is_none(); - nth - } - } - - #[inline] - fn last(self) -> Option { - if self.done { - None - } else { - self.iter.last() - } - } - - #[inline] - fn count(self) -> usize { - if self.done { - 0 - } else { - self.iter.count() - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - if self.done { - (0, Some(0)) - } else { - self.iter.size_hint() - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator { - #[inline] - fn next_back(&mut self) -> Option<::Item> { - if self.done { - None - } else { - let next = self.iter.next_back(); - self.done = next.is_none(); - next - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Fuse where I: ExactSizeIterator {} - -/// An iterator that calls a function with a reference to each element before -/// yielding it. -/// -/// This `struct` is created by the [`inspect()`] method on [`Iterator`]. See its -/// documentation for more. -/// -/// [`inspect()`]: trait.Iterator.html#method.inspect -/// [`Iterator`]: trait.Iterator.html -#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] -#[stable(feature = "rust1", since = "1.0.0")] -#[derive(Clone)] -pub struct Inspect { - iter: I, - f: F, -} - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Inspect { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.debug_struct("Inspect") - .field("iter", &self.iter) - .finish() - } -} - -impl Inspect where F: FnMut(&I::Item) { - #[inline] - fn do_inspect(&mut self, elt: Option) -> Option { - if let Some(ref a) = elt { - (self.f)(a); - } - - elt - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Inspect where F: FnMut(&I::Item) { - type Item = I::Item; - - #[inline] - fn next(&mut self) -> Option { - let next = self.iter.next(); - self.do_inspect(next) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - self.iter.size_hint() - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Inspect - where F: FnMut(&I::Item), -{ - #[inline] - fn next_back(&mut self) -> Option { - let next = self.iter.next_back(); - self.do_inspect(next) - } -} - -/// Objects that can be stepped over in both directions. -/// -/// The `steps_between` function provides a way to efficiently compare -/// two `Step` objects. -#[unstable(feature = "step_trait", - reason = "likely to be replaced by finer-grained traits", - issue = "27741")] -pub trait Step: PartialOrd + Sized { - /// Steps `self` if possible. - fn step(&self, by: &Self) -> Option; - - /// Returns the number of steps between two step objects. The count is - /// inclusive of `start` and exclusive of `end`. - /// - /// Returns `None` if it is not possible to calculate `steps_between` - /// without overflow. - fn steps_between(start: &Self, end: &Self, by: &Self) -> Option; -} - -macro_rules! step_impl_unsigned { - ($($t:ty)*) => ($( - #[unstable(feature = "step_trait", - reason = "likely to be replaced by finer-grained traits", - issue = "27741")] - impl Step for $t { - #[inline] - fn step(&self, by: &$t) -> Option<$t> { - (*self).checked_add(*by) - } - #[inline] - #[allow(trivial_numeric_casts)] - fn steps_between(start: &$t, end: &$t, by: &$t) -> Option { - if *by == 0 { return None; } - if *start < *end { - // Note: We assume $t <= usize here - let diff = (*end - *start) as usize; - let by = *by as usize; - if diff % by > 0 { - Some(diff / by + 1) - } else { - Some(diff / by) - } - } else { - Some(0) - } - } - } - )*) -} -macro_rules! step_impl_signed { - ($($t:ty)*) => ($( - #[unstable(feature = "step_trait", - reason = "likely to be replaced by finer-grained traits", - issue = "27741")] - impl Step for $t { - #[inline] - fn step(&self, by: &$t) -> Option<$t> { - (*self).checked_add(*by) - } - #[inline] - #[allow(trivial_numeric_casts)] - fn steps_between(start: &$t, end: &$t, by: &$t) -> Option { - if *by == 0 { return None; } - let diff: usize; - let by_u: usize; - if *by > 0 { - if *start >= *end { - return Some(0); - } - // Note: We assume $t <= isize here - // Use .wrapping_sub and cast to usize to compute the - // difference that may not fit inside the range of isize. - diff = (*end as isize).wrapping_sub(*start as isize) as usize; - by_u = *by as usize; - } else { - if *start <= *end { - return Some(0); - } - diff = (*start as isize).wrapping_sub(*end as isize) as usize; - by_u = (*by as isize).wrapping_mul(-1) as usize; - } - if diff % by_u > 0 { - Some(diff / by_u + 1) - } else { - Some(diff / by_u) - } - } - } - )*) -} - -macro_rules! step_impl_no_between { - ($($t:ty)*) => ($( - #[unstable(feature = "step_trait", - reason = "likely to be replaced by finer-grained traits", - issue = "27741")] - impl Step for $t { - #[inline] - fn step(&self, by: &$t) -> Option<$t> { - (*self).checked_add(*by) - } - #[inline] - fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option { - None - } - } - )*) -} - -step_impl_unsigned!(usize u8 u16 u32); -step_impl_signed!(isize i8 i16 i32); -#[cfg(target_pointer_width = "64")] -step_impl_unsigned!(u64); -#[cfg(target_pointer_width = "64")] -step_impl_signed!(i64); -// If the target pointer width is not 64-bits, we -// assume here that it is less than 64-bits. -#[cfg(not(target_pointer_width = "64"))] -step_impl_no_between!(u64 i64); - -/// An adapter for stepping range iterators by a custom amount. -/// -/// The resulting iterator handles overflow by stopping. The `A` -/// parameter is the type being iterated over, while `R` is the range -/// type (usually one of `std::ops::{Range, RangeFrom, RangeInclusive}`. -#[derive(Clone, Debug)] -#[unstable(feature = "step_by", reason = "recent addition", - issue = "27741")] -pub struct StepBy { - step_by: A, - range: R, -} - -impl ops::RangeFrom { - /// Creates an iterator starting at the same point, but stepping by - /// the given amount at each iteration. - /// - /// # Examples - /// - /// ``` - /// # #![feature(step_by)] - /// - /// for i in (0u8..).step_by(2).take(10) { - /// println!("{}", i); - /// } - /// ``` - /// - /// This prints the first ten even natural integers (0 to 18). - #[unstable(feature = "step_by", reason = "recent addition", - issue = "27741")] - pub fn step_by(self, by: A) -> StepBy { - StepBy { - step_by: by, - range: self - } - } -} - -impl ops::Range { - /// Creates an iterator with the same range, but stepping by the - /// given amount at each iteration. - /// - /// The resulting iterator handles overflow by stopping. - /// - /// # Examples - /// - /// ``` - /// #![feature(step_by)] - /// - /// for i in (0..10).step_by(2) { - /// println!("{}", i); - /// } - /// ``` - /// - /// This prints: - /// - /// ```text - /// 0 - /// 2 - /// 4 - /// 6 - /// 8 - /// ``` - #[unstable(feature = "step_by", reason = "recent addition", - issue = "27741")] - pub fn step_by(self, by: A) -> StepBy { - StepBy { - step_by: by, - range: self - } - } -} - -impl ops::RangeInclusive { - /// Creates an iterator with the same range, but stepping by the - /// given amount at each iteration. - /// - /// The resulting iterator handles overflow by stopping. - /// - /// # Examples - /// - /// ``` - /// #![feature(step_by, inclusive_range_syntax)] - /// - /// for i in (0...10).step_by(2) { - /// println!("{}", i); - /// } - /// ``` - /// - /// This prints: - /// - /// ```text - /// 0 - /// 2 - /// 4 - /// 6 - /// 8 - /// 10 - /// ``` - #[unstable(feature = "step_by", reason = "recent addition", - issue = "27741")] - pub fn step_by(self, by: A) -> StepBy { - StepBy { - step_by: by, - range: self - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for StepBy> where - A: Clone, - for<'a> &'a A: Add<&'a A, Output = A> -{ - type Item = A; - - #[inline] - fn next(&mut self) -> Option { - let mut n = &self.range.start + &self.step_by; - mem::swap(&mut n, &mut self.range.start); - Some(n) - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - (usize::MAX, None) // Too bad we can't specify an infinite lower bound - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for StepBy> { - type Item = A; - - #[inline] - fn next(&mut self) -> Option { - let rev = self.step_by < A::zero(); - if (rev && self.range.start > self.range.end) || - (!rev && self.range.start < self.range.end) - { - match self.range.start.step(&self.step_by) { - Some(mut n) => { - mem::swap(&mut self.range.start, &mut n); - Some(n) - }, - None => { - let mut n = self.range.end.clone(); - mem::swap(&mut self.range.start, &mut n); - Some(n) - } - } - } else { - None - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - match Step::steps_between(&self.range.start, - &self.range.end, - &self.step_by) { - Some(hint) => (hint, Some(hint)), - None => (0, None) - } - } -} - -#[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] -impl Iterator for StepBy> { - type Item = A; - - #[inline] - fn next(&mut self) -> Option { - use ops::RangeInclusive::*; - - // this function has a sort of odd structure due to borrowck issues - // we may need to replace self.range, so borrows of start and end need to end early - - let (finishing, n) = match self.range { - Empty { .. } => return None, // empty iterators yield no values - - NonEmpty { ref mut start, ref mut end } => { - let zero = A::zero(); - let rev = self.step_by < zero; - - // march start towards (maybe past!) end and yield the old value - if (rev && start >= end) || - (!rev && start <= end) - { - match start.step(&self.step_by) { - Some(mut n) => { - mem::swap(start, &mut n); - (None, Some(n)) // yield old value, remain non-empty - }, - None => { - let mut n = end.clone(); - mem::swap(start, &mut n); - (None, Some(n)) // yield old value, remain non-empty - } - } - } else { - // found range in inconsistent state (start at or past end), so become empty - (Some(mem::replace(end, zero)), None) - } - } - }; - - // turn into an empty iterator if we've reached the end - if let Some(end) = finishing { - self.range = Empty { at: end }; - } - - n - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - use ops::RangeInclusive::*; - - match self.range { - Empty { .. } => (0, Some(0)), - - NonEmpty { ref start, ref end } => - match Step::steps_between(start, - end, - &self.step_by) { - Some(hint) => (hint.saturating_add(1), hint.checked_add(1)), - None => (0, None) - } - } - } -} - -macro_rules! range_exact_iter_impl { - ($($t:ty)*) => ($( - #[stable(feature = "rust1", since = "1.0.0")] - impl ExactSizeIterator for ops::Range<$t> { } - - #[unstable(feature = "inclusive_range", - reason = "recently added, follows RFC", - issue = "28237")] - impl ExactSizeIterator for ops::RangeInclusive<$t> { } - )*) -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for ops::Range where - for<'a> &'a A: Add<&'a A, Output = A> -{ - type Item = A; - - #[inline] - fn next(&mut self) -> Option { - if self.start < self.end { - let mut n = &self.start + &A::one(); - mem::swap(&mut n, &mut self.start); - Some(n) - } else { - None - } - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - match Step::steps_between(&self.start, &self.end, &A::one()) { - Some(hint) => (hint, Some(hint)), - None => (0, None) - } - } -} - -// Ranges of u64 and i64 are excluded because they cannot guarantee having -// a length <= usize::MAX, which is required by ExactSizeIterator. -range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32); - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for ops::Range where - for<'a> &'a A: Add<&'a A, Output = A>, - for<'a> &'a A: Sub<&'a A, Output = A> -{ - #[inline] - fn next_back(&mut self) -> Option { - if self.start < self.end { - self.end = &self.end - &A::one(); - Some(self.end.clone()) - } else { - None - } - } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for ops::RangeFrom where - for<'a> &'a A: Add<&'a A, Output = A> -{ - type Item = A; - - #[inline] - fn next(&mut self) -> Option { - let mut n = &self.start + &A::one(); - mem::swap(&mut n, &mut self.start); - Some(n) - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -impl Iterator for ops::RangeInclusive where - for<'a> &'a A: Add<&'a A, Output = A> -{ - type Item = A; - - #[inline] - fn next(&mut self) -> Option { - use ops::RangeInclusive::*; - - // this function has a sort of odd structure due to borrowck issues - // we may need to replace self, so borrows of self.start and self.end need to end early - - let (finishing, n) = match *self { - Empty { .. } => (None, None), // empty iterators yield no values - - NonEmpty { ref mut start, ref mut end } => { - if start == end { - (Some(mem::replace(end, A::one())), Some(mem::replace(start, A::one()))) - } else if start < end { - let one = A::one(); - let mut n = &*start + &one; - mem::swap(&mut n, start); - - // if the iterator is done iterating, it will change from NonEmpty to Empty - // to avoid unnecessary drops or clones, we'll reuse either start or end - // (they are equal now, so it doesn't matter which) - // to pull out end, we need to swap something back in -- use the previously - // created A::one() as a dummy value - - (if n == *end { Some(mem::replace(end, one)) } else { None }, - // ^ are we done yet? - Some(n)) // < the value to output - } else { - (Some(mem::replace(start, A::one())), None) - } - } - }; - - // turn into an empty iterator if this is the last value - if let Some(end) = finishing { - *self = Empty { at: end }; - } - - n - } - - #[inline] - fn size_hint(&self) -> (usize, Option) { - use ops::RangeInclusive::*; - - match *self { - Empty { .. } => (0, Some(0)), - - NonEmpty { ref start, ref end } => - match Step::steps_between(start, end, &A::one()) { - Some(hint) => (hint.saturating_add(1), hint.checked_add(1)), - None => (0, None), - } - } - } -} - -#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] -impl DoubleEndedIterator for ops::RangeInclusive where - for<'a> &'a A: Add<&'a A, Output = A>, - for<'a> &'a A: Sub<&'a A, Output = A> -{ - #[inline] - fn next_back(&mut self) -> Option { - use ops::RangeInclusive::*; - - // see Iterator::next for comments - - let (finishing, n) = match *self { - Empty { .. } => return None, - - NonEmpty { ref mut start, ref mut end } => { - if start == end { - (Some(mem::replace(start, A::one())), Some(mem::replace(end, A::one()))) - } else if start < end { - let one = A::one(); - let mut n = &*end - &one; - mem::swap(&mut n, end); - - (if n == *start { Some(mem::replace(start, one)) } else { None }, - Some(n)) - } else { - (Some(mem::replace(end, A::one())), None) - } - } - }; - - if let Some(start) = finishing { - *self = Empty { at: start }; - } - - n - } -} - -/// An iterator that repeats an element endlessly. -/// -/// This `struct` is created by the [`repeat()`] function. See its documentation for more. -/// -/// [`repeat()`]: fn.repeat.html -#[derive(Clone, Debug)] -#[stable(feature = "rust1", since = "1.0.0")] -pub struct Repeat { - element: A -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl Iterator for Repeat { - type Item = A; - - #[inline] - fn next(&mut self) -> Option { Some(self.element.clone()) } - #[inline] - fn size_hint(&self) -> (usize, Option) { (usize::MAX, None) } -} - -#[stable(feature = "rust1", since = "1.0.0")] -impl DoubleEndedIterator for Repeat { - #[inline] - fn next_back(&mut self) -> Option { Some(self.element.clone()) } -} - -/// Creates a new iterator that endlessly repeats a single element. -/// -/// The `repeat()` function repeats a single value over and over and over and -/// over and over and 🔁. -/// -/// Infinite iterators like `repeat()` are often used with adapters like -/// [`take()`], in order to make them finite. -/// -/// [`take()`]: trait.Iterator.html#method.take -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// use std::iter; -/// -/// // the number four 4ever: -/// let mut fours = iter::repeat(4); -/// -/// assert_eq!(Some(4), fours.next()); -/// assert_eq!(Some(4), fours.next()); -/// assert_eq!(Some(4), fours.next()); -/// assert_eq!(Some(4), fours.next()); -/// assert_eq!(Some(4), fours.next()); -/// -/// // yup, still four -/// assert_eq!(Some(4), fours.next()); -/// ``` -/// -/// Going finite with [`take()`]: -/// -/// ``` -/// use std::iter; -/// -/// // that last example was too many fours. Let's only have four fours. -/// let mut four_fours = iter::repeat(4).take(4); -/// -/// assert_eq!(Some(4), four_fours.next()); -/// assert_eq!(Some(4), four_fours.next()); -/// assert_eq!(Some(4), four_fours.next()); -/// assert_eq!(Some(4), four_fours.next()); -/// -/// // ... and now we're done -/// assert_eq!(None, four_fours.next()); -/// ``` -#[inline] -#[stable(feature = "rust1", since = "1.0.0")] -pub fn repeat(elt: T) -> Repeat { - Repeat{element: elt} -} - -/// An iterator that yields nothing. -/// -/// This `struct` is created by the [`empty()`] function. See its documentation for more. -/// -/// [`empty()`]: fn.empty.html -#[stable(feature = "iter_empty", since = "1.2.0")] -pub struct Empty(marker::PhantomData); - -#[stable(feature = "core_impl_debug", since = "1.9.0")] -impl fmt::Debug for Empty { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad("Empty") - } -} - -#[stable(feature = "iter_empty", since = "1.2.0")] -impl Iterator for Empty { - type Item = T; - - fn next(&mut self) -> Option { - None - } - - fn size_hint(&self) -> (usize, Option){ - (0, Some(0)) - } -} - -#[stable(feature = "iter_empty", since = "1.2.0")] -impl DoubleEndedIterator for Empty { - fn next_back(&mut self) -> Option { - None - } -} - -#[stable(feature = "iter_empty", since = "1.2.0")] -impl ExactSizeIterator for Empty { - fn len(&self) -> usize { - 0 - } -} - -// not #[derive] because that adds a Clone bound on T, -// which isn't necessary. -#[stable(feature = "iter_empty", since = "1.2.0")] -impl Clone for Empty { - fn clone(&self) -> Empty { - Empty(marker::PhantomData) - } -} - -// not #[derive] because that adds a Default bound on T, -// which isn't necessary. -#[stable(feature = "iter_empty", since = "1.2.0")] -impl Default for Empty { - fn default() -> Empty { - Empty(marker::PhantomData) - } -} - -/// Creates an iterator that yields nothing. -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// use std::iter; -/// -/// // this could have been an iterator over i32, but alas, it's just not. -/// let mut nope = iter::empty::(); -/// -/// assert_eq!(None, nope.next()); -/// ``` -#[stable(feature = "iter_empty", since = "1.2.0")] -pub fn empty() -> Empty { - Empty(marker::PhantomData) -} - -/// An iterator that yields an element exactly once. -/// -/// This `struct` is created by the [`once()`] function. See its documentation for more. -/// -/// [`once()`]: fn.once.html -#[derive(Clone, Debug)] -#[stable(feature = "iter_once", since = "1.2.0")] -pub struct Once { - inner: ::option::IntoIter -} - -#[stable(feature = "iter_once", since = "1.2.0")] -impl Iterator for Once { - type Item = T; - - fn next(&mut self) -> Option { - self.inner.next() - } - - fn size_hint(&self) -> (usize, Option) { - self.inner.size_hint() - } -} - -#[stable(feature = "iter_once", since = "1.2.0")] -impl DoubleEndedIterator for Once { - fn next_back(&mut self) -> Option { - self.inner.next_back() - } -} - -#[stable(feature = "iter_once", since = "1.2.0")] -impl ExactSizeIterator for Once { - fn len(&self) -> usize { - self.inner.len() - } -} - -/// Creates an iterator that yields an element exactly once. -/// -/// This is commonly used to adapt a single value into a [`chain()`] of other -/// kinds of iteration. Maybe you have an iterator that covers almost -/// everything, but you need an extra special case. Maybe you have a function -/// which works on iterators, but you only need to process one value. -/// -/// [`chain()`]: trait.Iterator.html#method.chain -/// -/// # Examples -/// -/// Basic usage: -/// -/// ``` -/// use std::iter; -/// -/// // one is the loneliest number -/// let mut one = iter::once(1); -/// -/// assert_eq!(Some(1), one.next()); -/// -/// // just one, that's all we get -/// assert_eq!(None, one.next()); -/// ``` -/// -/// Chaining together with another iterator. Let's say that we want to iterate -/// over each file of the `.foo` directory, but also a configuration file, -/// `.foorc`: -/// -/// ```no_run -/// use std::iter; -/// use std::fs; -/// use std::path::PathBuf; -/// -/// let dirs = fs::read_dir(".foo").unwrap(); -/// -/// // we need to convert from an iterator of DirEntry-s to an iterator of -/// // PathBufs, so we use map -/// let dirs = dirs.map(|file| file.unwrap().path()); -/// -/// // now, our iterator just for our config file -/// let config = iter::once(PathBuf::from(".foorc")); -/// -/// // chain the two iterators together into one big iterator -/// let files = dirs.chain(config); -/// -/// // this will give us all of the files in .foo as well as .foorc -/// for f in files { -/// println!("{:?}", f); -/// } -/// ``` -#[stable(feature = "iter_once", since = "1.2.0")] -pub fn once(value: T) -> Once { - Once { inner: Some(value).into_iter() } -} diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs new file mode 100644 index 00000000000..0cc83d42ce0 --- /dev/null +++ b/src/libcore/iter/iterator.rs @@ -0,0 +1,2109 @@ +// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use clone::Clone; +use cmp::{Ord, PartialOrd, PartialEq, Ordering}; +use default::Default; +use marker; +use num::{Zero, One}; +use ops::{Add, FnMut, Mul}; +use option::Option::{self, Some, None}; +use marker::Sized; + +use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev, Zip}; +use super::ChainState; +use super::{DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator}; + +fn _assert_is_object_safe(_: &Iterator) {} + +/// An interface for dealing with iterators. +/// +/// This is the main iterator trait. For more about the concept of iterators +/// generally, please see the [module-level documentation]. In particular, you +/// may want to know how to [implement `Iterator`][impl]. +/// +/// [module-level documentation]: index.html +/// [impl]: index.html#implementing-iterator +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_on_unimplemented = "`{Self}` is not an iterator; maybe try calling \ + `.iter()` or a similar method"] +pub trait Iterator { + /// The type of the elements being iterated over. + #[stable(feature = "rust1", since = "1.0.0")] + type Item; + + /// Advances the iterator and returns the next value. + /// + /// Returns `None` when iteration is finished. Individual iterator + /// implementations may choose to resume iteration, and so calling `next()` + /// again may or may not eventually start returning `Some(Item)` again at some + /// point. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// // A call to next() returns the next value... + /// assert_eq!(Some(&1), iter.next()); + /// assert_eq!(Some(&2), iter.next()); + /// assert_eq!(Some(&3), iter.next()); + /// + /// // ... and then None once it's over. + /// assert_eq!(None, iter.next()); + /// + /// // More calls may or may not return None. Here, they always will. + /// assert_eq!(None, iter.next()); + /// assert_eq!(None, iter.next()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn next(&mut self) -> Option; + + /// Returns the bounds on the remaining length of the iterator. + /// + /// Specifically, `size_hint()` returns a tuple where the first element + /// is the lower bound, and the second element is the upper bound. + /// + /// The second half of the tuple that is returned is an `Option`. A + /// `None` here means that either there is no known upper bound, or the + /// upper bound is larger than `usize`. + /// + /// # Implementation notes + /// + /// It is not enforced that an iterator implementation yields the declared + /// number of elements. A buggy iterator may yield less than the lower bound + /// or more than the upper bound of elements. + /// + /// `size_hint()` is primarily intended to be used for optimizations such as + /// reserving space for the elements of the iterator, but must not be + /// trusted to e.g. omit bounds checks in unsafe code. An incorrect + /// implementation of `size_hint()` should not lead to memory safety + /// violations. + /// + /// That said, the implementation should provide a correct estimation, + /// because otherwise it would be a violation of the trait's protocol. + /// + /// The default implementation returns `(0, None)` which is correct for any + /// iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// let iter = a.iter(); + /// + /// assert_eq!((3, Some(3)), iter.size_hint()); + /// ``` + /// + /// A more complex example: + /// + /// ``` + /// // The even numbers from zero to ten. + /// let iter = (0..10).filter(|x| x % 2 == 0); + /// + /// // We might iterate from zero to ten times. Knowing that it's five + /// // exactly wouldn't be possible without executing filter(). + /// assert_eq!((0, Some(10)), iter.size_hint()); + /// + /// // Let's add one five more numbers with chain() + /// let iter = (0..10).filter(|x| x % 2 == 0).chain(15..20); + /// + /// // now both bounds are increased by five + /// assert_eq!((5, Some(15)), iter.size_hint()); + /// ``` + /// + /// Returning `None` for an upper bound: + /// + /// ``` + /// // an infinite iterator has no upper bound + /// let iter = 0..; + /// + /// assert_eq!((0, None), iter.size_hint()); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn size_hint(&self) -> (usize, Option) { (0, None) } + + /// Consumes the iterator, counting the number of iterations and returning it. + /// + /// This method will evaluate the iterator until its [`next()`] returns + /// `None`. Once `None` is encountered, `count()` returns the number of + /// times it called [`next()`]. + /// + /// [`next()`]: #tymethod.next + /// + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so counting elements of + /// an iterator with more than `usize::MAX` elements either produces the + /// wrong result or panics. If debug assertions are enabled, a panic is + /// guaranteed. + /// + /// # Panics + /// + /// This function might panic if the iterator has more than `usize::MAX` + /// elements. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().count(), 3); + /// + /// let a = [1, 2, 3, 4, 5]; + /// assert_eq!(a.iter().count(), 5); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn count(self) -> usize where Self: Sized { + // Might overflow. + self.fold(0, |cnt, _| cnt + 1) + } + + /// Consumes the iterator, returning the last element. + /// + /// This method will evaluate the iterator until it returns `None`. While + /// doing so, it keeps track of the current element. After `None` is + /// returned, `last()` will then return the last element it saw. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().last(), Some(&3)); + /// + /// let a = [1, 2, 3, 4, 5]; + /// assert_eq!(a.iter().last(), Some(&5)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn last(self) -> Option where Self: Sized { + let mut last = None; + for x in self { last = Some(x); } + last + } + + /// Consumes the `n` first elements of the iterator, then returns the + /// `next()` one. + /// + /// This method will evaluate the iterator `n` times, discarding those elements. + /// After it does so, it will call [`next()`] and return its value. + /// + /// [`next()`]: #tymethod.next + /// + /// Like most indexing operations, the count starts from zero, so `nth(0)` + /// returns the first value, `nth(1)` the second, and so on. + /// + /// `nth()` will return `None` if `n` is larger than the length of the + /// iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().nth(1), Some(&2)); + /// ``` + /// + /// Calling `nth()` multiple times doesn't rewind the iterator: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.nth(1), Some(&2)); + /// assert_eq!(iter.nth(1), None); + /// ``` + /// + /// Returning `None` if there are less than `n` elements: + /// + /// ``` + /// let a = [1, 2, 3]; + /// assert_eq!(a.iter().nth(10), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn nth(&mut self, mut n: usize) -> Option where Self: Sized { + for x in self { + if n == 0 { return Some(x) } + n -= 1; + } + None + } + + /// Takes two iterators and creates a new iterator over both in sequence. + /// + /// `chain()` will return a new iterator which will first iterate over + /// values from the first iterator and then over values from the second + /// iterator. + /// + /// In other words, it links two iterators together, in a chain. 🔗 + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a1 = [1, 2, 3]; + /// let a2 = [4, 5, 6]; + /// + /// let mut iter = a1.iter().chain(a2.iter()); + /// + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(&4)); + /// assert_eq!(iter.next(), Some(&5)); + /// assert_eq!(iter.next(), Some(&6)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Since the argument to `chain()` uses [`IntoIterator`], we can pass + /// anything that can be converted into an [`Iterator`], not just an + /// [`Iterator`] itself. For example, slices (`&[T]`) implement + /// [`IntoIterator`], and so can be passed to `chain()` directly: + /// + /// [`IntoIterator`]: trait.IntoIterator.html + /// [`Iterator`]: trait.Iterator.html + /// + /// ``` + /// let s1 = &[1, 2, 3]; + /// let s2 = &[4, 5, 6]; + /// + /// let mut iter = s1.iter().chain(s2); + /// + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(&4)); + /// assert_eq!(iter.next(), Some(&5)); + /// assert_eq!(iter.next(), Some(&6)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn chain(self, other: U) -> Chain where + Self: Sized, U: IntoIterator, + { + Chain{a: self, b: other.into_iter(), state: ChainState::Both} + } + + /// 'Zips up' two iterators into a single iterator of pairs. + /// + /// `zip()` returns a new iterator that will iterate over two other + /// iterators, returning a tuple where the first element comes from the + /// first iterator, and the second element comes from the second iterator. + /// + /// In other words, it zips two iterators together, into a single one. + /// + /// When either iterator returns `None`, all further calls to `next()` + /// will return `None`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a1 = [1, 2, 3]; + /// let a2 = [4, 5, 6]; + /// + /// let mut iter = a1.iter().zip(a2.iter()); + /// + /// assert_eq!(iter.next(), Some((&1, &4))); + /// assert_eq!(iter.next(), Some((&2, &5))); + /// assert_eq!(iter.next(), Some((&3, &6))); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Since the argument to `zip()` uses [`IntoIterator`], we can pass + /// anything that can be converted into an [`Iterator`], not just an + /// [`Iterator`] itself. For example, slices (`&[T]`) implement + /// [`IntoIterator`], and so can be passed to `zip()` directly: + /// + /// [`IntoIterator`]: trait.IntoIterator.html + /// [`Iterator`]: trait.Iterator.html + /// + /// ``` + /// let s1 = &[1, 2, 3]; + /// let s2 = &[4, 5, 6]; + /// + /// let mut iter = s1.iter().zip(s2); + /// + /// assert_eq!(iter.next(), Some((&1, &4))); + /// assert_eq!(iter.next(), Some((&2, &5))); + /// assert_eq!(iter.next(), Some((&3, &6))); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// `zip()` is often used to zip an infinite iterator to a finite one. + /// This works because the finite iterator will eventually return `None`, + /// ending the zipper. Zipping with `(0..)` can look a lot like [`enumerate()`]: + /// + /// ``` + /// let enumerate: Vec<_> = "foo".chars().enumerate().collect(); + /// + /// let zipper: Vec<_> = (0..).zip("foo".chars()).collect(); + /// + /// assert_eq!((0, 'f'), enumerate[0]); + /// assert_eq!((0, 'f'), zipper[0]); + /// + /// assert_eq!((1, 'o'), enumerate[1]); + /// assert_eq!((1, 'o'), zipper[1]); + /// + /// assert_eq!((2, 'o'), enumerate[2]); + /// assert_eq!((2, 'o'), zipper[2]); + /// ``` + /// + /// [`enumerate()`]: trait.Iterator.html#method.enumerate + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn zip(self, other: U) -> Zip where + Self: Sized, U: IntoIterator + { + Zip{a: self, b: other.into_iter()} + } + + /// Takes a closure and creates an iterator which calls that closure on each + /// element. + /// + /// `map()` transforms one iterator into another, by means of its argument: + /// something that implements `FnMut`. It produces a new iterator which + /// calls this closure on each element of the original iterator. + /// + /// If you are good at thinking in types, you can think of `map()` like this: + /// If you have an iterator that gives you elements of some type `A`, and + /// you want an iterator of some other type `B`, you can use `map()`, + /// passing a closure that takes an `A` and returns a `B`. + /// + /// `map()` is conceptually similar to a [`for`] loop. However, as `map()` is + /// lazy, it is best used when you're already working with other iterators. + /// If you're doing some sort of looping for a side effect, it's considered + /// more idiomatic to use [`for`] than `map()`. + /// + /// [`for`]: ../../book/loops.html#for + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.into_iter().map(|x| 2 * x); + /// + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), Some(4)); + /// assert_eq!(iter.next(), Some(6)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// If you're doing some sort of side effect, prefer [`for`] to `map()`: + /// + /// ``` + /// # #![allow(unused_must_use)] + /// // don't do this: + /// (0..5).map(|x| println!("{}", x)); + /// + /// // it won't even execute, as it is lazy. Rust will warn you about this. + /// + /// // Instead, use for: + /// for x in 0..5 { + /// println!("{}", x); + /// } + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn map(self, f: F) -> Map where + Self: Sized, F: FnMut(Self::Item) -> B, + { + Map{iter: self, f: f} + } + + /// Creates an iterator which uses a closure to determine if an element + /// should be yielded. + /// + /// The closure must return `true` or `false`. `filter()` creates an + /// iterator which calls this closure on each element. If the closure + /// returns `true`, then the element is returned. If the closure returns + /// `false`, it will try again, and call the closure on the next element, + /// seeing if it passes the test. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [0i32, 1, 2]; + /// + /// let mut iter = a.into_iter().filter(|x| x.is_positive()); + /// + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Because the closure passed to `filter()` takes a reference, and many + /// iterators iterate over references, this leads to a possibly confusing + /// situation, where the type of the closure is a double reference: + /// + /// ``` + /// let a = [0, 1, 2]; + /// + /// let mut iter = a.into_iter().filter(|x| **x > 1); // need two *s! + /// + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// It's common to instead use destructuring on the argument to strip away + /// one: + /// + /// ``` + /// let a = [0, 1, 2]; + /// + /// let mut iter = a.into_iter().filter(|&x| *x > 1); // both & and * + /// + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// or both: + /// + /// ``` + /// let a = [0, 1, 2]; + /// + /// let mut iter = a.into_iter().filter(|&&x| x > 1); // two &s + /// + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// of these layers. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn filter

(self, predicate: P) -> Filter where + Self: Sized, P: FnMut(&Self::Item) -> bool, + { + Filter{iter: self, predicate: predicate} + } + + /// Creates an iterator that both filters and maps. + /// + /// The closure must return an [`Option`]. `filter_map()` creates an + /// iterator which calls this closure on each element. If the closure + /// returns `Some(element)`, then that element is returned. If the + /// closure returns `None`, it will try again, and call the closure on the + /// next element, seeing if it will return `Some`. + /// + /// [`Option`]: ../../std/option/enum.Option.html + /// + /// Why `filter_map()` and not just [`filter()`].[`map()`]? The key is in this + /// part: + /// + /// [`filter()`]: #method.filter + /// [`map()`]: #method.map + /// + /// > If the closure returns `Some(element)`, then that element is returned. + /// + /// In other words, it removes the [`Option`] layer automatically. If your + /// mapping is already returning an [`Option`] and you want to skip over + /// `None`s, then `filter_map()` is much, much nicer to use. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = ["1", "2", "lol"]; + /// + /// let mut iter = a.iter().filter_map(|s| s.parse().ok()); + /// + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Here's the same example, but with [`filter()`] and [`map()`]: + /// + /// ``` + /// let a = ["1", "2", "lol"]; + /// + /// let mut iter = a.iter() + /// .map(|s| s.parse().ok()) + /// .filter(|s| s.is_some()); + /// + /// assert_eq!(iter.next(), Some(Some(1))); + /// assert_eq!(iter.next(), Some(Some(2))); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// There's an extra layer of `Some` in there. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn filter_map(self, f: F) -> FilterMap where + Self: Sized, F: FnMut(Self::Item) -> Option, + { + FilterMap { iter: self, f: f } + } + + /// Creates an iterator which gives the current iteration count as well as + /// the next value. + /// + /// The iterator returned yields pairs `(i, val)`, where `i` is the + /// current index of iteration and `val` is the value returned by the + /// iterator. + /// + /// `enumerate()` keeps its count as a [`usize`]. If you want to count by a + /// different sized integer, the [`zip()`] function provides similar + /// functionality. + /// + /// [`usize`]: ../../std/primitive.usize.html + /// [`zip()`]: #method.zip + /// + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so enumerating more than + /// [`usize::MAX`] elements either produces the wrong result or panics. If + /// debug assertions are enabled, a panic is guaranteed. + /// + /// [`usize::MAX`]: ../../std/usize/constant.MAX.html + /// + /// # Panics + /// + /// The returned iterator might panic if the to-be-returned index would + /// overflow a `usize`. + /// + /// # Examples + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().enumerate(); + /// + /// assert_eq!(iter.next(), Some((0, &1))); + /// assert_eq!(iter.next(), Some((1, &2))); + /// assert_eq!(iter.next(), Some((2, &3))); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn enumerate(self) -> Enumerate where Self: Sized { + Enumerate { iter: self, count: 0 } + } + + /// Creates an iterator which can use `peek` to look at the next element of + /// the iterator without consuming it. + /// + /// Adds a [`peek()`] method to an iterator. See its documentation for + /// more information. + /// + /// Note that the underlying iterator is still advanced when `peek` is + /// called for the first time: In order to retrieve the next element, + /// `next` is called on the underlying iterator, hence any side effects of + /// the `next` method will occur. + /// + /// [`peek()`]: struct.Peekable.html#method.peek + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let xs = [1, 2, 3]; + /// + /// let mut iter = xs.iter().peekable(); + /// + /// // peek() lets us see into the future + /// assert_eq!(iter.peek(), Some(&&1)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// assert_eq!(iter.next(), Some(&2)); + /// + /// // we can peek() multiple times, the iterator won't advance + /// assert_eq!(iter.peek(), Some(&&3)); + /// assert_eq!(iter.peek(), Some(&&3)); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// + /// // after the iterator is finished, so is peek() + /// assert_eq!(iter.peek(), None); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn peekable(self) -> Peekable where Self: Sized { + Peekable{iter: self, peeked: None} + } + + /// Creates an iterator that [`skip()`]s elements based on a predicate. + /// + /// [`skip()`]: #method.skip + /// + /// `skip_while()` takes a closure as an argument. It will call this + /// closure on each element of the iterator, and ignore elements + /// until it returns `false`. + /// + /// After `false` is returned, `skip_while()`'s job is over, and the + /// rest of the elements are yielded. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [-1i32, 0, 1]; + /// + /// let mut iter = a.into_iter().skip_while(|x| x.is_negative()); + /// + /// assert_eq!(iter.next(), Some(&0)); + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Because the closure passed to `skip_while()` takes a reference, and many + /// iterators iterate over references, this leads to a possibly confusing + /// situation, where the type of the closure is a double reference: + /// + /// ``` + /// let a = [-1, 0, 1]; + /// + /// let mut iter = a.into_iter().skip_while(|x| **x < 0); // need two *s! + /// + /// assert_eq!(iter.next(), Some(&0)); + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Stopping after an initial `false`: + /// + /// ``` + /// let a = [-1, 0, 1, -2]; + /// + /// let mut iter = a.into_iter().skip_while(|x| **x < 0); + /// + /// assert_eq!(iter.next(), Some(&0)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// // while this would have been false, since we already got a false, + /// // skip_while() isn't used any more + /// assert_eq!(iter.next(), Some(&-2)); + /// + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn skip_while

(self, predicate: P) -> SkipWhile where + Self: Sized, P: FnMut(&Self::Item) -> bool, + { + SkipWhile{iter: self, flag: false, predicate: predicate} + } + + /// Creates an iterator that yields elements based on a predicate. + /// + /// `take_while()` takes a closure as an argument. It will call this + /// closure on each element of the iterator, and yield elements + /// while it returns `true`. + /// + /// After `false` is returned, `take_while()`'s job is over, and the + /// rest of the elements are ignored. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [-1i32, 0, 1]; + /// + /// let mut iter = a.into_iter().take_while(|x| x.is_negative()); + /// + /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Because the closure passed to `take_while()` takes a reference, and many + /// iterators iterate over references, this leads to a possibly confusing + /// situation, where the type of the closure is a double reference: + /// + /// ``` + /// let a = [-1, 0, 1]; + /// + /// let mut iter = a.into_iter().take_while(|x| **x < 0); // need two *s! + /// + /// assert_eq!(iter.next(), Some(&-1)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Stopping after an initial `false`: + /// + /// ``` + /// let a = [-1, 0, 1, -2]; + /// + /// let mut iter = a.into_iter().take_while(|x| **x < 0); + /// + /// assert_eq!(iter.next(), Some(&-1)); + /// + /// // We have more elements that are less than zero, but since we already + /// // got a false, take_while() isn't used any more + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// Because `take_while()` needs to look at the value in order to see if it + /// should be included or not, consuming iterators will see that it is + /// removed: + /// + /// ``` + /// let a = [1, 2, 3, 4]; + /// let mut iter = a.into_iter(); + /// + /// let result: Vec = iter.by_ref() + /// .take_while(|n| **n != 3) + /// .cloned() + /// .collect(); + /// + /// assert_eq!(result, &[1, 2]); + /// + /// let result: Vec = iter.cloned().collect(); + /// + /// assert_eq!(result, &[4]); + /// ``` + /// + /// The `3` is no longer there, because it was consumed in order to see if + /// the iteration should stop, but wasn't placed back into the iterator or + /// some similar thing. + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn take_while

(self, predicate: P) -> TakeWhile where + Self: Sized, P: FnMut(&Self::Item) -> bool, + { + TakeWhile{iter: self, flag: false, predicate: predicate} + } + + /// Creates an iterator that skips the first `n` elements. + /// + /// After they have been consumed, the rest of the elements are yielded. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().skip(2); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn skip(self, n: usize) -> Skip where Self: Sized { + Skip{iter: self, n: n} + } + + /// Creates an iterator that yields its first `n` elements. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().take(2); + /// + /// assert_eq!(iter.next(), Some(&1)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), None); + /// ``` + /// + /// `take()` is often used with an infinite iterator, to make it finite: + /// + /// ``` + /// let mut iter = (0..).take(3); + /// + /// assert_eq!(iter.next(), Some(0)); + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn take(self, n: usize) -> Take where Self: Sized, { + Take{iter: self, n: n} + } + + /// An iterator adaptor similar to [`fold()`] that holds internal state and + /// produces a new iterator. + /// + /// [`fold()`]: #method.fold + /// + /// `scan()` takes two arguments: an initial value which seeds the internal + /// state, and a closure with two arguments, the first being a mutable + /// reference to the internal state and the second an iterator element. + /// The closure can assign to the internal state to share state between + /// iterations. + /// + /// On iteration, the closure will be applied to each element of the + /// iterator and the return value from the closure, an [`Option`], is + /// yielded by the iterator. + /// + /// [`Option`]: ../../std/option/enum.Option.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().scan(1, |state, &x| { + /// // each iteration, we'll multiply the state by the element + /// *state = *state * x; + /// + /// // the value passed on to the next iteration + /// Some(*state) + /// }); + /// + /// assert_eq!(iter.next(), Some(1)); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), Some(6)); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn scan(self, initial_state: St, f: F) -> Scan + where Self: Sized, F: FnMut(&mut St, Self::Item) -> Option, + { + Scan{iter: self, f: f, state: initial_state} + } + + /// Creates an iterator that works like map, but flattens nested structure. + /// + /// The [`map()`] adapter is very useful, but only when the closure + /// argument produces values. If it produces an iterator instead, there's + /// an extra layer of indirection. `flat_map()` will remove this extra layer + /// on its own. + /// + /// [`map()`]: #method.map + /// + /// Another way of thinking about `flat_map()`: [`map()`]'s closure returns + /// one item for each element, and `flat_map()`'s closure returns an + /// iterator for each element. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let words = ["alpha", "beta", "gamma"]; + /// + /// // chars() returns an iterator + /// let merged: String = words.iter() + /// .flat_map(|s| s.chars()) + /// .collect(); + /// assert_eq!(merged, "alphabetagamma"); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn flat_map(self, f: F) -> FlatMap + where Self: Sized, U: IntoIterator, F: FnMut(Self::Item) -> U, + { + FlatMap{iter: self, f: f, frontiter: None, backiter: None } + } + + /// Creates an iterator which ends after the first `None`. + /// + /// After an iterator returns `None`, future calls may or may not yield + /// `Some(T)` again. `fuse()` adapts an iterator, ensuring that after a + /// `None` is given, it will always return `None` forever. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // an iterator which alternates between Some and None + /// struct Alternate { + /// state: i32, + /// } + /// + /// impl Iterator for Alternate { + /// type Item = i32; + /// + /// fn next(&mut self) -> Option { + /// let val = self.state; + /// self.state = self.state + 1; + /// + /// // if it's even, Some(i32), else None + /// if val % 2 == 0 { + /// Some(val) + /// } else { + /// None + /// } + /// } + /// } + /// + /// let mut iter = Alternate { state: 0 }; + /// + /// // we can see our iterator going back and forth + /// assert_eq!(iter.next(), Some(0)); + /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), Some(2)); + /// assert_eq!(iter.next(), None); + /// + /// // however, once we fuse it... + /// let mut iter = iter.fuse(); + /// + /// assert_eq!(iter.next(), Some(4)); + /// assert_eq!(iter.next(), None); + /// + /// // it will always return None after the first time. + /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), None); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn fuse(self) -> Fuse where Self: Sized { + Fuse{iter: self, done: false} + } + + /// Do something with each element of an iterator, passing the value on. + /// + /// When using iterators, you'll often chain several of them together. + /// While working on such code, you might want to check out what's + /// happening at various parts in the pipeline. To do that, insert + /// a call to `inspect()`. + /// + /// It's much more common for `inspect()` to be used as a debugging tool + /// than to exist in your final code, but never say never. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 4, 2, 3]; + /// + /// // this iterator sequence is complex. + /// let sum = a.iter() + /// .cloned() + /// .filter(|&x| x % 2 == 0) + /// .fold(0, |sum, i| sum + i); + /// + /// println!("{}", sum); + /// + /// // let's add some inspect() calls to investigate what's happening + /// let sum = a.iter() + /// .cloned() + /// .inspect(|x| println!("about to filter: {}", x)) + /// .filter(|&x| x % 2 == 0) + /// .inspect(|x| println!("made it through filter: {}", x)) + /// .fold(0, |sum, i| sum + i); + /// + /// println!("{}", sum); + /// ``` + /// + /// This will print: + /// + /// ```text + /// about to filter: 1 + /// about to filter: 4 + /// made it through filter: 4 + /// about to filter: 2 + /// made it through filter: 2 + /// about to filter: 3 + /// 6 + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn inspect(self, f: F) -> Inspect where + Self: Sized, F: FnMut(&Self::Item), + { + Inspect{iter: self, f: f} + } + + /// Borrows an iterator, rather than consuming it. + /// + /// This is useful to allow applying iterator adaptors while still + /// retaining ownership of the original iterator. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let iter = a.into_iter(); + /// + /// let sum: i32 = iter.take(5) + /// .fold(0, |acc, &i| acc + i ); + /// + /// assert_eq!(sum, 6); + /// + /// // if we try to use iter again, it won't work. The following line + /// // gives "error: use of moved value: `iter` + /// // assert_eq!(iter.next(), None); + /// + /// // let's try that again + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.into_iter(); + /// + /// // instead, we add in a .by_ref() + /// let sum: i32 = iter.by_ref() + /// .take(2) + /// .fold(0, |acc, &i| acc + i ); + /// + /// assert_eq!(sum, 3); + /// + /// // now this is just fine: + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), None); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn by_ref(&mut self) -> &mut Self where Self: Sized { self } + + /// Transforms an iterator into a collection. + /// + /// `collect()` can take anything iterable, and turn it into a relevant + /// collection. This is one of the more powerful methods in the standard + /// library, used in a variety of contexts. + /// + /// The most basic pattern in which `collect()` is used is to turn one + /// collection into another. You take a collection, call `iter()` on it, + /// do a bunch of transformations, and then `collect()` at the end. + /// + /// One of the keys to `collect()`'s power is that many things you might + /// not think of as 'collections' actually are. For example, a [`String`] + /// is a collection of [`char`]s. And a collection of [`Result`] can + /// be thought of as single `Result, E>`. See the examples + /// below for more. + /// + /// [`String`]: ../../std/string/struct.String.html + /// [`Result`]: ../../std/result/enum.Result.html + /// [`char`]: ../../std/primitive.char.html + /// + /// Because `collect()` is so general, it can cause problems with type + /// inference. As such, `collect()` is one of the few times you'll see + /// the syntax affectionately known as the 'turbofish': `::<>`. This + /// helps the inference algorithm understand specifically which collection + /// you're trying to collect into. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let doubled: Vec = a.iter() + /// .map(|&x| x * 2) + /// .collect(); + /// + /// assert_eq!(vec![2, 4, 6], doubled); + /// ``` + /// + /// Note that we needed the `: Vec` on the left-hand side. This is because + /// we could collect into, for example, a [`VecDeque`] instead: + /// + /// [`VecDeque`]: ../../std/collections/struct.VecDeque.html + /// + /// ``` + /// use std::collections::VecDeque; + /// + /// let a = [1, 2, 3]; + /// + /// let doubled: VecDeque = a.iter() + /// .map(|&x| x * 2) + /// .collect(); + /// + /// assert_eq!(2, doubled[0]); + /// assert_eq!(4, doubled[1]); + /// assert_eq!(6, doubled[2]); + /// ``` + /// + /// Using the 'turbofish' instead of annotating `doubled`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let doubled = a.iter() + /// .map(|&x| x * 2) + /// .collect::>(); + /// + /// assert_eq!(vec![2, 4, 6], doubled); + /// ``` + /// + /// Because `collect()` cares about what you're collecting into, you can + /// still use a partial type hint, `_`, with the turbofish: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let doubled = a.iter() + /// .map(|&x| x * 2) + /// .collect::>(); + /// + /// assert_eq!(vec![2, 4, 6], doubled); + /// ``` + /// + /// Using `collect()` to make a [`String`]: + /// + /// ``` + /// let chars = ['g', 'd', 'k', 'k', 'n']; + /// + /// let hello: String = chars.iter() + /// .map(|&x| x as u8) + /// .map(|x| (x + 1) as char) + /// .collect(); + /// + /// assert_eq!("hello", hello); + /// ``` + /// + /// If you have a list of [`Result`]s, you can use `collect()` to + /// see if any of them failed: + /// + /// ``` + /// let results = [Ok(1), Err("nope"), Ok(3), Err("bad")]; + /// + /// let result: Result, &str> = results.iter().cloned().collect(); + /// + /// // gives us the first error + /// assert_eq!(Err("nope"), result); + /// + /// let results = [Ok(1), Ok(3)]; + /// + /// let result: Result, &str> = results.iter().cloned().collect(); + /// + /// // gives us the list of answers + /// assert_eq!(Ok(vec![1, 3]), result); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn collect>(self) -> B where Self: Sized { + FromIterator::from_iter(self) + } + + /// Consumes an iterator, creating two collections from it. + /// + /// The predicate passed to `partition()` can return `true`, or `false`. + /// `partition()` returns a pair, all of the elements for which it returned + /// `true`, and all of the elements for which it returned `false`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let (even, odd): (Vec, Vec) = a.into_iter() + /// .partition(|&n| n % 2 == 0); + /// + /// assert_eq!(even, vec![2]); + /// assert_eq!(odd, vec![1, 3]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn partition(self, mut f: F) -> (B, B) where + Self: Sized, + B: Default + Extend, + F: FnMut(&Self::Item) -> bool + { + let mut left: B = Default::default(); + let mut right: B = Default::default(); + + for x in self { + if f(&x) { + left.extend(Some(x)) + } else { + right.extend(Some(x)) + } + } + + (left, right) + } + + /// An iterator adaptor that applies a function, producing a single, final value. + /// + /// `fold()` takes two arguments: an initial value, and a closure with two + /// arguments: an 'accumulator', and an element. The closure returns the value that + /// the accumulator should have for the next iteration. + /// + /// The initial value is the value the accumulator will have on the first + /// call. + /// + /// After applying this closure to every element of the iterator, `fold()` + /// returns the accumulator. + /// + /// This operation is sometimes called 'reduce' or 'inject'. + /// + /// Folding is useful whenever you have a collection of something, and want + /// to produce a single value from it. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// // the sum of all of the elements of a + /// let sum = a.iter() + /// .fold(0, |acc, &x| acc + x); + /// + /// assert_eq!(sum, 6); + /// ``` + /// + /// Let's walk through each step of the iteration here: + /// + /// | element | acc | x | result | + /// |---------|-----|---|--------| + /// | | 0 | | | + /// | 1 | 0 | 1 | 1 | + /// | 2 | 1 | 2 | 3 | + /// | 3 | 3 | 3 | 6 | + /// + /// And so, our final result, `6`. + /// + /// It's common for people who haven't used iterators a lot to + /// use a `for` loop with a list of things to build up a result. Those + /// can be turned into `fold()`s: + /// + /// ``` + /// let numbers = [1, 2, 3, 4, 5]; + /// + /// let mut result = 0; + /// + /// // for loop: + /// for i in &numbers { + /// result = result + i; + /// } + /// + /// // fold: + /// let result2 = numbers.iter().fold(0, |acc, &x| acc + x); + /// + /// // they're the same + /// assert_eq!(result, result2); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn fold(self, init: B, mut f: F) -> B where + Self: Sized, F: FnMut(B, Self::Item) -> B, + { + let mut accum = init; + for x in self { + accum = f(accum, x); + } + accum + } + + /// Tests if every element of the iterator matches a predicate. + /// + /// `all()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, and if they all return + /// `true`, then so does `all()`. If any of them return `false`, it + /// returns `false`. + /// + /// `all()` is short-circuiting; in other words, it will stop processing + /// as soon as it finds a `false`, given that no matter what else happens, + /// the result will also be `false`. + /// + /// An empty iterator returns `true`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert!(a.iter().all(|&x| x > 0)); + /// + /// assert!(!a.iter().all(|&x| x > 2)); + /// ``` + /// + /// Stopping at the first `false`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert!(!iter.all(|&x| x != 2)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn all(&mut self, mut f: F) -> bool where + Self: Sized, F: FnMut(Self::Item) -> bool + { + for x in self { + if !f(x) { + return false; + } + } + true + } + + /// Tests if any element of the iterator matches a predicate. + /// + /// `any()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, and if any of them return + /// `true`, then so does `any()`. If they all return `false`, it + /// returns `false`. + /// + /// `any()` is short-circuiting; in other words, it will stop processing + /// as soon as it finds a `true`, given that no matter what else happens, + /// the result will also be `true`. + /// + /// An empty iterator returns `false`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert!(a.iter().any(|&x| x > 0)); + /// + /// assert!(!a.iter().any(|&x| x > 5)); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert!(iter.any(|&x| x != 2)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&2)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn any(&mut self, mut f: F) -> bool where + Self: Sized, + F: FnMut(Self::Item) -> bool + { + for x in self { + if f(x) { + return true; + } + } + false + } + + /// Searches for an element of an iterator that satisfies a predicate. + /// + /// `find()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, and if any of them return + /// `true`, then `find()` returns `Some(element)`. If they all return + /// `false`, it returns `None`. + /// + /// `find()` is short-circuiting; in other words, it will stop processing + /// as soon as the closure returns `true`. + /// + /// Because `find()` takes a reference, and many iterators iterate over + /// references, this leads to a possibly confusing situation where the + /// argument is a double reference. You can see this effect in the + /// examples below, with `&&x`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().find(|&&x| x == 2), Some(&2)); + /// + /// assert_eq!(a.iter().find(|&&x| x == 5), None); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.find(|&&x| x == 2), Some(&2)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn find

(&mut self, mut predicate: P) -> Option where + Self: Sized, + P: FnMut(&Self::Item) -> bool, + { + for x in self { + if predicate(&x) { return Some(x) } + } + None + } + + /// Searches for an element in an iterator, returning its index. + /// + /// `position()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, and if one of them + /// returns `true`, then `position()` returns `Some(index)`. If all of + /// them return `false`, it returns `None`. + /// + /// `position()` is short-circuiting; in other words, it will stop + /// processing as soon as it finds a `true`. + /// + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so if there are more + /// than `usize::MAX` non-matching elements, it either produces the wrong + /// result or panics. If debug assertions are enabled, a panic is + /// guaranteed. + /// + /// # Panics + /// + /// This function might panic if the iterator has more than `usize::MAX` + /// non-matching elements. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().position(|&x| x == 2), Some(1)); + /// + /// assert_eq!(a.iter().position(|&x| x == 5), None); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.position(|&x| x == 2), Some(1)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn position

(&mut self, mut predicate: P) -> Option where + Self: Sized, + P: FnMut(Self::Item) -> bool, + { + // `enumerate` might overflow. + for (i, x) in self.enumerate() { + if predicate(x) { + return Some(i); + } + } + None + } + + /// Searches for an element in an iterator from the right, returning its + /// index. + /// + /// `rposition()` takes a closure that returns `true` or `false`. It applies + /// this closure to each element of the iterator, starting from the end, + /// and if one of them returns `true`, then `rposition()` returns + /// `Some(index)`. If all of them return `false`, it returns `None`. + /// + /// `rposition()` is short-circuiting; in other words, it will stop + /// processing as soon as it finds a `true`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().rposition(|&x| x == 3), Some(2)); + /// + /// assert_eq!(a.iter().rposition(|&x| x == 5), None); + /// ``` + /// + /// Stopping at the first `true`: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter(); + /// + /// assert_eq!(iter.rposition(|&x| x == 2), Some(1)); + /// + /// // we can still use `iter`, as there are more elements. + /// assert_eq!(iter.next(), Some(&1)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn rposition

(&mut self, mut predicate: P) -> Option where + P: FnMut(Self::Item) -> bool, + Self: Sized + ExactSizeIterator + DoubleEndedIterator + { + let mut i = self.len(); + + while let Some(v) = self.next_back() { + if predicate(v) { + return Some(i - 1); + } + // No need for an overflow check here, because `ExactSizeIterator` + // implies that the number of elements fits into a `usize`. + i -= 1; + } + None + } + + /// Returns the maximum element of an iterator. + /// + /// If the two elements are equally maximum, the latest element is + /// returned. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().max(), Some(&3)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn max(self) -> Option where Self: Sized, Self::Item: Ord + { + select_fold1(self, + |_| (), + // switch to y even if it is only equal, to preserve + // stability. + |_, x, _, y| *x <= *y) + .map(|(_, x)| x) + } + + /// Returns the minimum element of an iterator. + /// + /// If the two elements are equally minimum, the first element is + /// returned. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// assert_eq!(a.iter().min(), Some(&1)); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn min(self) -> Option where Self: Sized, Self::Item: Ord + { + select_fold1(self, + |_| (), + // only switch to y if it is strictly smaller, to + // preserve stability. + |_, x, _, y| *x > *y) + .map(|(_, x)| x) + } + + /// Returns the element that gives the maximum value from the + /// specified function. + /// + /// Returns the rightmost element if the comparison determines two elements + /// to be equally maximum. + /// + /// # Examples + /// + /// ``` + /// let a = [-3_i32, 0, 1, 5, -10]; + /// assert_eq!(*a.iter().max_by_key(|x| x.abs()).unwrap(), -10); + /// ``` + #[inline] + #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] + fn max_by_key(self, f: F) -> Option + where Self: Sized, F: FnMut(&Self::Item) -> B, + { + select_fold1(self, + f, + // switch to y even if it is only equal, to preserve + // stability. + |x_p, _, y_p, _| x_p <= y_p) + .map(|(_, x)| x) + } + + /// Returns the element that gives the minimum value from the + /// specified function. + /// + /// Returns the latest element if the comparison determines two elements + /// to be equally minimum. + /// + /// # Examples + /// + /// ``` + /// let a = [-3_i32, 0, 1, 5, -10]; + /// assert_eq!(*a.iter().min_by_key(|x| x.abs()).unwrap(), 0); + /// ``` + #[stable(feature = "iter_cmp_by_key", since = "1.6.0")] + fn min_by_key(self, f: F) -> Option + where Self: Sized, F: FnMut(&Self::Item) -> B, + { + select_fold1(self, + f, + // only switch to y if it is strictly smaller, to + // preserve stability. + |x_p, _, y_p, _| x_p > y_p) + .map(|(_, x)| x) + } + + /// Reverses an iterator's direction. + /// + /// Usually, iterators iterate from left to right. After using `rev()`, + /// an iterator will instead iterate from right to left. + /// + /// This is only possible if the iterator has an end, so `rev()` only + /// works on [`DoubleEndedIterator`]s. + /// + /// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html + /// + /// # Examples + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut iter = a.iter().rev(); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// assert_eq!(iter.next(), Some(&2)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + fn rev(self) -> Rev where Self: Sized + DoubleEndedIterator { + Rev{iter: self} + } + + /// Converts an iterator of pairs into a pair of containers. + /// + /// `unzip()` consumes an entire iterator of pairs, producing two + /// collections: one from the left elements of the pairs, and one + /// from the right elements. + /// + /// This function is, in some sense, the opposite of [`zip()`]. + /// + /// [`zip()`]: #method.zip + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [(1, 2), (3, 4)]; + /// + /// let (left, right): (Vec<_>, Vec<_>) = a.iter().cloned().unzip(); + /// + /// assert_eq!(left, [1, 3]); + /// assert_eq!(right, [2, 4]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn unzip(self) -> (FromA, FromB) where + FromA: Default + Extend, + FromB: Default + Extend, + Self: Sized + Iterator, + { + struct SizeHint(usize, Option, marker::PhantomData); + impl Iterator for SizeHint { + type Item = A; + + fn next(&mut self) -> Option { None } + fn size_hint(&self) -> (usize, Option) { + (self.0, self.1) + } + } + + let (lo, hi) = self.size_hint(); + let mut ts: FromA = Default::default(); + let mut us: FromB = Default::default(); + + ts.extend(SizeHint(lo, hi, marker::PhantomData)); + us.extend(SizeHint(lo, hi, marker::PhantomData)); + + for (t, u) in self { + ts.extend(Some(t)); + us.extend(Some(u)); + } + + (ts, us) + } + + /// Creates an iterator which `clone()`s all of its elements. + /// + /// This is useful when you have an iterator over `&T`, but you need an + /// iterator over `T`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let v_cloned: Vec<_> = a.iter().cloned().collect(); + /// + /// // cloned is the same as .map(|&x| x), for integers + /// let v_map: Vec<_> = a.iter().map(|&x| x).collect(); + /// + /// assert_eq!(v_cloned, vec![1, 2, 3]); + /// assert_eq!(v_map, vec![1, 2, 3]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn cloned<'a, T: 'a>(self) -> Cloned + where Self: Sized + Iterator, T: Clone + { + Cloned { it: self } + } + + /// Repeats an iterator endlessly. + /// + /// Instead of stopping at `None`, the iterator will instead start again, + /// from the beginning. After iterating again, it will start at the + /// beginning again. And again. And again. Forever. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let a = [1, 2, 3]; + /// + /// let mut it = a.iter().cycle(); + /// + /// assert_eq!(it.next(), Some(&1)); + /// assert_eq!(it.next(), Some(&2)); + /// assert_eq!(it.next(), Some(&3)); + /// assert_eq!(it.next(), Some(&1)); + /// assert_eq!(it.next(), Some(&2)); + /// assert_eq!(it.next(), Some(&3)); + /// assert_eq!(it.next(), Some(&1)); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + #[inline] + fn cycle(self) -> Cycle where Self: Sized + Clone { + Cycle{orig: self.clone(), iter: self} + } + + /// Sums the elements of an iterator. + /// + /// Takes each element, adds them together, and returns the result. + /// + /// An empty iterator returns the zero value of the type. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(iter_arith)] + /// + /// let a = [1, 2, 3]; + /// let sum: i32 = a.iter().sum(); + /// + /// assert_eq!(sum, 6); + /// ``` + #[unstable(feature = "iter_arith", reason = "bounds recently changed", + issue = "27739")] + fn sum(self) -> S where + S: Add + Zero, + Self: Sized, + { + self.fold(Zero::zero(), |s, e| s + e) + } + + /// Iterates over the entire iterator, multiplying all the elements + /// + /// An empty iterator returns the one value of the type. + /// + /// # Examples + /// + /// ``` + /// #![feature(iter_arith)] + /// + /// fn factorial(n: u32) -> u32 { + /// (1..).take_while(|&i| i <= n).product() + /// } + /// assert_eq!(factorial(0), 1); + /// assert_eq!(factorial(1), 1); + /// assert_eq!(factorial(5), 120); + /// ``` + #[unstable(feature="iter_arith", reason = "bounds recently changed", + issue = "27739")] + fn product

(self) -> P where + P: Mul + One, + Self: Sized, + { + self.fold(One::one(), |p, e| p * e) + } + + /// Lexicographically compares the elements of this `Iterator` with those + /// of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn cmp(mut self, other: I) -> Ordering where + I: IntoIterator, + Self::Item: Ord, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return Ordering::Equal, + (None, _ ) => return Ordering::Less, + (_ , None) => return Ordering::Greater, + (Some(x), Some(y)) => match x.cmp(&y) { + Ordering::Equal => (), + non_eq => return non_eq, + }, + } + } + } + + /// Lexicographically compares the elements of this `Iterator` with those + /// of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn partial_cmp(mut self, other: I) -> Option where + I: IntoIterator, + Self::Item: PartialOrd, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return Some(Ordering::Equal), + (None, _ ) => return Some(Ordering::Less), + (_ , None) => return Some(Ordering::Greater), + (Some(x), Some(y)) => match x.partial_cmp(&y) { + Some(Ordering::Equal) => (), + non_eq => return non_eq, + }, + } + } + } + + /// Determines if the elements of this `Iterator` are equal to those of + /// another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn eq(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialEq, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return true, + (None, _) | (_, None) => return false, + (Some(x), Some(y)) => if x != y { return false }, + } + } + } + + /// Determines if the elements of this `Iterator` are unequal to those of + /// another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn ne(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialEq, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return false, + (None, _) | (_, None) => return true, + (Some(x), Some(y)) => if x.ne(&y) { return true }, + } + } + } + + /// Determines if the elements of this `Iterator` are lexicographically + /// less than those of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn lt(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialOrd, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return false, + (None, _ ) => return true, + (_ , None) => return false, + (Some(x), Some(y)) => { + match x.partial_cmp(&y) { + Some(Ordering::Less) => return true, + Some(Ordering::Equal) => {} + Some(Ordering::Greater) => return false, + None => return false, + } + }, + } + } + } + + /// Determines if the elements of this `Iterator` are lexicographically + /// less or equal to those of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn le(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialOrd, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return true, + (None, _ ) => return true, + (_ , None) => return false, + (Some(x), Some(y)) => { + match x.partial_cmp(&y) { + Some(Ordering::Less) => return true, + Some(Ordering::Equal) => {} + Some(Ordering::Greater) => return false, + None => return false, + } + }, + } + } + } + + /// Determines if the elements of this `Iterator` are lexicographically + /// greater than those of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn gt(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialOrd, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return false, + (None, _ ) => return false, + (_ , None) => return true, + (Some(x), Some(y)) => { + match x.partial_cmp(&y) { + Some(Ordering::Less) => return false, + Some(Ordering::Equal) => {} + Some(Ordering::Greater) => return true, + None => return false, + } + } + } + } + } + + /// Determines if the elements of this `Iterator` are lexicographically + /// greater than or equal to those of another. + #[stable(feature = "iter_order", since = "1.5.0")] + fn ge(mut self, other: I) -> bool where + I: IntoIterator, + Self::Item: PartialOrd, + Self: Sized, + { + let mut other = other.into_iter(); + + loop { + match (self.next(), other.next()) { + (None, None) => return true, + (None, _ ) => return false, + (_ , None) => return true, + (Some(x), Some(y)) => { + match x.partial_cmp(&y) { + Some(Ordering::Less) => return false, + Some(Ordering::Equal) => {} + Some(Ordering::Greater) => return true, + None => return false, + } + }, + } + } + } +} + +/// Select an element from an iterator based on the given projection +/// and "comparison" function. +/// +/// This is an idiosyncratic helper to try to factor out the +/// commonalities of {max,min}{,_by}. In particular, this avoids +/// having to implement optimizations several times. +#[inline] +fn select_fold1(mut it: I, + mut f_proj: FProj, + mut f_cmp: FCmp) -> Option<(B, I::Item)> + where I: Iterator, + FProj: FnMut(&I::Item) -> B, + FCmp: FnMut(&B, &I::Item, &B, &I::Item) -> bool +{ + // start with the first element as our selection. This avoids + // having to use `Option`s inside the loop, translating to a + // sizeable performance gain (6x in one case). + it.next().map(|mut sel| { + let mut sel_p = f_proj(&sel); + + for x in it { + let x_p = f_proj(&x); + if f_cmp(&sel_p, &sel, &x_p, &x) { + sel = x; + sel_p = x_p; + } + } + (sel_p, sel) + }) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I { + type Item = I::Item; + fn next(&mut self) -> Option { (**self).next() } + fn size_hint(&self) -> (usize, Option) { (**self).size_hint() } +} + diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs new file mode 100644 index 00000000000..8449ee78501 --- /dev/null +++ b/src/libcore/iter/mod.rs @@ -0,0 +1,1657 @@ +// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! Composable external iteration. +//! +//! If you've found yourself with a collection of some kind, and needed to +//! perform an operation on the elements of said collection, you'll quickly run +//! into 'iterators'. Iterators are heavily used in idiomatic Rust code, so +//! it's worth becoming familiar with them. +//! +//! Before explaining more, let's talk about how this module is structured: +//! +//! # Organization +//! +//! This module is largely organized by type: +//! +//! * [Traits] are the core portion: these traits define what kind of iterators +//! exist and what you can do with them. The methods of these traits are worth +//! putting some extra study time into. +//! * [Functions] provide some helpful ways to create some basic iterators. +//! * [Structs] are often the return types of the various methods on this +//! module's traits. You'll usually want to look at the method that creates +//! the `struct`, rather than the `struct` itself. For more detail about why, +//! see '[Implementing Iterator](#implementing-iterator)'. +//! +//! [Traits]: #traits +//! [Functions]: #functions +//! [Structs]: #structs +//! +//! That's it! Let's dig into iterators. +//! +//! # Iterator +//! +//! The heart and soul of this module is the [`Iterator`] trait. The core of +//! [`Iterator`] looks like this: +//! +//! ``` +//! trait Iterator { +//! type Item; +//! fn next(&mut self) -> Option; +//! } +//! ``` +//! +//! An iterator has a method, [`next()`], which when called, returns an +//! [`Option`]``. [`next()`] will return `Some(Item)` as long as there +//! are elements, and once they've all been exhausted, will return `None` to +//! indicate that iteration is finished. Individual iterators may choose to +//! resume iteration, and so calling [`next()`] again may or may not eventually +//! start returning `Some(Item)` again at some point. +//! +//! [`Iterator`]'s full definition includes a number of other methods as well, +//! but they are default methods, built on top of [`next()`], and so you get +//! them for free. +//! +//! Iterators are also composable, and it's common to chain them together to do +//! more complex forms of processing. See the [Adapters](#adapters) section +//! below for more details. +//! +//! [`Iterator`]: trait.Iterator.html +//! [`next()`]: trait.Iterator.html#tymethod.next +//! [`Option`]: ../../std/option/enum.Option.html +//! +//! # The three forms of iteration +//! +//! There are three common methods which can create iterators from a collection: +//! +//! * `iter()`, which iterates over `&T`. +//! * `iter_mut()`, which iterates over `&mut T`. +//! * `into_iter()`, which iterates over `T`. +//! +//! Various things in the standard library may implement one or more of the +//! three, where appropriate. +//! +//! # Implementing Iterator +//! +//! Creating an iterator of your own involves two steps: creating a `struct` to +//! hold the iterator's state, and then `impl`ementing [`Iterator`] for that +//! `struct`. This is why there are so many `struct`s in this module: there is +//! one for each iterator and iterator adapter. +//! +//! Let's make an iterator named `Counter` which counts from `1` to `5`: +//! +//! ``` +//! // First, the struct: +//! +//! /// An iterator which counts from one to five +//! struct Counter { +//! count: usize, +//! } +//! +//! // we want our count to start at one, so let's add a new() method to help. +//! // This isn't strictly necessary, but is convenient. Note that we start +//! // `count` at zero, we'll see why in `next()`'s implementation below. +//! impl Counter { +//! fn new() -> Counter { +//! Counter { count: 0 } +//! } +//! } +//! +//! // Then, we implement `Iterator` for our `Counter`: +//! +//! impl Iterator for Counter { +//! // we will be counting with usize +//! type Item = usize; +//! +//! // next() is the only required method +//! fn next(&mut self) -> Option { +//! // increment our count. This is why we started at zero. +//! self.count += 1; +//! +//! // check to see if we've finished counting or not. +//! if self.count < 6 { +//! Some(self.count) +//! } else { +//! None +//! } +//! } +//! } +//! +//! // And now we can use it! +//! +//! let mut counter = Counter::new(); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! +//! let x = counter.next().unwrap(); +//! println!("{}", x); +//! ``` +//! +//! This will print `1` through `5`, each on their own line. +//! +//! Calling `next()` this way gets repetitive. Rust has a construct which can +//! call `next()` on your iterator, until it reaches `None`. Let's go over that +//! next. +//! +//! # for Loops and IntoIterator +//! +//! Rust's `for` loop syntax is actually sugar for iterators. Here's a basic +//! example of `for`: +//! +//! ``` +//! let values = vec![1, 2, 3, 4, 5]; +//! +//! for x in values { +//! println!("{}", x); +//! } +//! ``` +//! +//! This will print the numbers one through five, each on their own line. But +//! you'll notice something here: we never called anything on our vector to +//! produce an iterator. What gives? +//! +//! There's a trait in the standard library for converting something into an +//! iterator: [`IntoIterator`]. This trait has one method, [`into_iter()`], +//! which converts the thing implementing [`IntoIterator`] into an iterator. +//! Let's take a look at that `for` loop again, and what the compiler converts +//! it into: +//! +//! [`IntoIterator`]: trait.IntoIterator.html +//! [`into_iter()`]: trait.IntoIterator.html#tymethod.into_iter +//! +//! ``` +//! let values = vec![1, 2, 3, 4, 5]; +//! +//! for x in values { +//! println!("{}", x); +//! } +//! ``` +//! +//! Rust de-sugars this into: +//! +//! ``` +//! let values = vec![1, 2, 3, 4, 5]; +//! { +//! let result = match IntoIterator::into_iter(values) { +//! mut iter => loop { +//! match iter.next() { +//! Some(x) => { println!("{}", x); }, +//! None => break, +//! } +//! }, +//! }; +//! result +//! } +//! ``` +//! +//! First, we call `into_iter()` on the value. Then, we match on the iterator +//! that returns, calling [`next()`] over and over until we see a `None`. At +//! that point, we `break` out of the loop, and we're done iterating. +//! +//! There's one more subtle bit here: the standard library contains an +//! interesting implementation of [`IntoIterator`]: +//! +//! ```ignore +//! impl IntoIterator for I +//! ``` +//! +//! In other words, all [`Iterator`]s implement [`IntoIterator`], by just +//! returning themselves. This means two things: +//! +//! 1. If you're writing an [`Iterator`], you can use it with a `for` loop. +//! 2. If you're creating a collection, implementing [`IntoIterator`] for it +//! will allow your collection to be used with the `for` loop. +//! +//! # Adapters +//! +//! Functions which take an [`Iterator`] and return another [`Iterator`] are +//! often called 'iterator adapters', as they're a form of the 'adapter +//! pattern'. +//! +//! Common iterator adapters include [`map()`], [`take()`], and [`collect()`]. +//! For more, see their documentation. +//! +//! [`map()`]: trait.Iterator.html#method.map +//! [`take()`]: trait.Iterator.html#method.take +//! [`collect()`]: trait.Iterator.html#method.collect +//! +//! # Laziness +//! +//! Iterators (and iterator [adapters](#adapters)) are *lazy*. This means that +//! just creating an iterator doesn't _do_ a whole lot. Nothing really happens +//! until you call [`next()`]. This is sometimes a source of confusion when +//! creating an iterator solely for its side effects. For example, the [`map()`] +//! method calls a closure on each element it iterates over: +//! +//! ``` +//! # #![allow(unused_must_use)] +//! let v = vec![1, 2, 3, 4, 5]; +//! v.iter().map(|x| println!("{}", x)); +//! ``` +//! +//! This will not print any values, as we only created an iterator, rather than +//! using it. The compiler will warn us about this kind of behavior: +//! +//! ```text +//! warning: unused result which must be used: iterator adaptors are lazy and +//! do nothing unless consumed +//! ``` +//! +//! The idiomatic way to write a [`map()`] for its side effects is to use a +//! `for` loop instead: +//! +//! ``` +//! let v = vec![1, 2, 3, 4, 5]; +//! +//! for x in &v { +//! println!("{}", x); +//! } +//! ``` +//! +//! [`map()`]: trait.Iterator.html#method.map +//! +//! The two most common ways to evaluate an iterator are to use a `for` loop +//! like this, or using the [`collect()`] adapter to produce a new collection. +//! +//! [`collect()`]: trait.Iterator.html#method.collect +//! +//! # Infinity +//! +//! Iterators do not have to be finite. As an example, an open-ended range is +//! an infinite iterator: +//! +//! ``` +//! let numbers = 0..; +//! ``` +//! +//! It is common to use the [`take()`] iterator adapter to turn an infinite +//! iterator into a finite one: +//! +//! ``` +//! let numbers = 0..; +//! let five_numbers = numbers.take(5); +//! +//! for number in five_numbers { +//! println!("{}", number); +//! } +//! ``` +//! +//! This will print the numbers `0` through `4`, each on their own line. +//! +//! [`take()`]: trait.Iterator.html#method.take + +#![stable(feature = "rust1", since = "1.0.0")] + +use clone::Clone; +use cmp; +use fmt; +use ops::FnMut; +use option::Option::{self, Some, None}; +use usize; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::iterator::Iterator; + +#[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] +pub use self::range::Step; +#[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] +pub use self::range::StepBy; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::sources::{Repeat, repeat}; +#[stable(feature = "iter_empty", since = "1.2.0")] +pub use self::sources::{Empty, empty}; +#[stable(feature = "iter_once", since = "1.2.0")] +pub use self::sources::{Once, once}; + +#[stable(feature = "rust1", since = "1.0.0")] +pub use self::traits::{FromIterator, IntoIterator, DoubleEndedIterator, Extend, + ExactSizeIterator}; + +mod iterator; +mod range; +mod sources; +mod traits; + +// All adaptors that preserve the size of the wrapped iterator are fine +// Adaptors that may overflow in `size_hint` are not, i.e. `Chain`. +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Enumerate where I: ExactSizeIterator {} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Inspect where + F: FnMut(&I::Item), +{} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Rev + where I: ExactSizeIterator + DoubleEndedIterator {} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Map where + F: FnMut(I::Item) -> B, +{} +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Zip + where A: ExactSizeIterator, B: ExactSizeIterator {} + +/// An double-ended iterator with the direction inverted. +/// +/// This `struct` is created by the [`rev()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`rev()`]: trait.Iterator.html#method.rev +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Rev { + iter: T +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Rev where I: DoubleEndedIterator { + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option<::Item> { self.iter.next_back() } + #[inline] + fn size_hint(&self) -> (usize, Option) { self.iter.size_hint() } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Rev where I: DoubleEndedIterator { + #[inline] + fn next_back(&mut self) -> Option<::Item> { self.iter.next() } +} + +/// An iterator that clones the elements of an underlying iterator. +/// +/// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`cloned()`]: trait.Iterator.html#method.cloned +/// [`Iterator`]: trait.Iterator.html +#[stable(feature = "iter_cloned", since = "1.1.0")] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[derive(Clone, Debug)] +pub struct Cloned { + it: I, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I, T: 'a> Iterator for Cloned + where I: Iterator, T: Clone +{ + type Item = T; + + fn next(&mut self) -> Option { + self.it.next().cloned() + } + + fn size_hint(&self) -> (usize, Option) { + self.it.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I, T: 'a> DoubleEndedIterator for Cloned + where I: DoubleEndedIterator, T: Clone +{ + fn next_back(&mut self) -> Option { + self.it.next_back().cloned() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I, T: 'a> ExactSizeIterator for Cloned + where I: ExactSizeIterator, T: Clone +{} + +/// An iterator that repeats endlessly. +/// +/// This `struct` is created by the [`cycle()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`cycle()`]: trait.Iterator.html#method.cycle +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Cycle { + orig: I, + iter: I, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Cycle where I: Clone + Iterator { + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option<::Item> { + match self.iter.next() { + None => { self.iter = self.orig.clone(); self.iter.next() } + y => y + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + // the cycle iterator is either empty or infinite + match self.orig.size_hint() { + sz @ (0, Some(0)) => sz, + (0, _) => (0, None), + _ => (usize::MAX, None) + } + } +} + +/// An iterator that strings two iterators together. +/// +/// This `struct` is created by the [`chain()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`chain()`]: trait.Iterator.html#method.chain +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Chain { + a: A, + b: B, + state: ChainState, +} + +// The iterator protocol specifies that iteration ends with the return value +// `None` from `.next()` (or `.next_back()`) and it is unspecified what +// further calls return. The chain adaptor must account for this since it uses +// two subiterators. +// +// It uses three states: +// +// - Both: `a` and `b` are remaining +// - Front: `a` remaining +// - Back: `b` remaining +// +// The fourth state (neither iterator is remaining) only occurs after Chain has +// returned None once, so we don't need to store this state. +#[derive(Clone, Debug)] +enum ChainState { + // both front and back iterator are remaining + Both, + // only front is remaining + Front, + // only back is remaining + Back, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Chain where + A: Iterator, + B: Iterator +{ + type Item = A::Item; + + #[inline] + fn next(&mut self) -> Option { + match self.state { + ChainState::Both => match self.a.next() { + elt @ Some(..) => elt, + None => { + self.state = ChainState::Back; + self.b.next() + } + }, + ChainState::Front => self.a.next(), + ChainState::Back => self.b.next(), + } + } + + #[inline] + fn count(self) -> usize { + match self.state { + ChainState::Both => self.a.count() + self.b.count(), + ChainState::Front => self.a.count(), + ChainState::Back => self.b.count(), + } + } + + #[inline] + fn nth(&mut self, mut n: usize) -> Option { + match self.state { + ChainState::Both | ChainState::Front => { + for x in self.a.by_ref() { + if n == 0 { + return Some(x) + } + n -= 1; + } + if let ChainState::Both = self.state { + self.state = ChainState::Back; + } + } + ChainState::Back => {} + } + if let ChainState::Back = self.state { + self.b.nth(n) + } else { + None + } + } + + #[inline] + fn last(self) -> Option { + match self.state { + ChainState::Both => { + // Must exhaust a before b. + let a_last = self.a.last(); + let b_last = self.b.last(); + b_last.or(a_last) + }, + ChainState::Front => self.a.last(), + ChainState::Back => self.b.last() + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = a_lower.saturating_add(b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => x.checked_add(y), + _ => None + }; + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Chain where + A: DoubleEndedIterator, + B: DoubleEndedIterator, +{ + #[inline] + fn next_back(&mut self) -> Option { + match self.state { + ChainState::Both => match self.b.next_back() { + elt @ Some(..) => elt, + None => { + self.state = ChainState::Front; + self.a.next_back() + } + }, + ChainState::Front => self.a.next_back(), + ChainState::Back => self.b.next_back(), + } + } +} + +/// An iterator that iterates two other iterators simultaneously. +/// +/// This `struct` is created by the [`zip()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`zip()`]: trait.Iterator.html#method.zip +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Zip { + a: A, + b: B +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Zip where A: Iterator, B: Iterator +{ + type Item = (A::Item, B::Item); + + #[inline] + fn next(&mut self) -> Option<(A::Item, B::Item)> { + self.a.next().and_then(|x| { + self.b.next().and_then(|y| { + Some((x, y)) + }) + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (a_lower, a_upper) = self.a.size_hint(); + let (b_lower, b_upper) = self.b.size_hint(); + + let lower = cmp::min(a_lower, b_lower); + + let upper = match (a_upper, b_upper) { + (Some(x), Some(y)) => Some(cmp::min(x,y)), + (Some(x), None) => Some(x), + (None, Some(y)) => Some(y), + (None, None) => None + }; + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Zip where + A: DoubleEndedIterator + ExactSizeIterator, + B: DoubleEndedIterator + ExactSizeIterator, +{ + #[inline] + fn next_back(&mut self) -> Option<(A::Item, B::Item)> { + let a_sz = self.a.len(); + let b_sz = self.b.len(); + if a_sz != b_sz { + // Adjust a, b to equal length + if a_sz > b_sz { + for _ in 0..a_sz - b_sz { self.a.next_back(); } + } else { + for _ in 0..b_sz - a_sz { self.b.next_back(); } + } + } + match (self.a.next_back(), self.b.next_back()) { + (Some(x), Some(y)) => Some((x, y)), + (None, None) => None, + _ => unreachable!(), + } + } +} + +/// An iterator that maps the values of `iter` with `f`. +/// +/// This `struct` is created by the [`map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`map()`]: trait.Iterator.html#method.map +/// [`Iterator`]: trait.Iterator.html +/// +/// # Notes about side effects +/// +/// The [`map()`] iterator implements [`DoubleEndedIterator`], meaning that +/// you can also [`map()`] backwards: +/// +/// ```rust +/// let v: Vec = vec![1, 2, 3].into_iter().rev().map(|x| x + 1).collect(); +/// +/// assert_eq!(v, [4, 3, 2]); +/// ``` +/// +/// [`DoubleEndedIterator`]: trait.DoubleEndedIterator.html +/// +/// But if your closure has state, iterating backwards may act in a way you do +/// not expect. Let's go through an example. First, in the forward direction: +/// +/// ```rust +/// let mut c = 0; +/// +/// for pair in vec!['a', 'b', 'c'].into_iter() +/// .map(|letter| { c += 1; (letter, c) }) { +/// println!("{:?}", pair); +/// } +/// ``` +/// +/// This will print "('a', 1), ('b', 2), ('c', 3)". +/// +/// Now consider this twist where we add a call to `rev`. This version will +/// print `('c', 1), ('b', 2), ('a', 3)`. Note that the letters are reversed, +/// but the values of the counter still go in order. This is because `map()` is +/// still being called lazilly on each item, but we are popping items off the +/// back of the vector now, instead of shifting them from the front. +/// +/// ```rust +/// let mut c = 0; +/// +/// for pair in vec!['a', 'b', 'c'].into_iter() +/// .map(|letter| { c += 1; (letter, c) }) +/// .rev() { +/// println!("{:?}", pair); +/// } +/// ``` +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Map { + iter: I, + f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Map { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Map") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Map where F: FnMut(I::Item) -> B { + type Item = B; + + #[inline] + fn next(&mut self) -> Option { + self.iter.next().map(&mut self.f) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Map where + F: FnMut(I::Item) -> B, +{ + #[inline] + fn next_back(&mut self) -> Option { + self.iter.next_back().map(&mut self.f) + } +} + +/// An iterator that filters the elements of `iter` with `predicate`. +/// +/// This `struct` is created by the [`filter()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter()`]: trait.Iterator.html#method.filter +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Filter { + iter: I, + predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Filter { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Filter") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Filter where P: FnMut(&I::Item) -> bool { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + for x in self.iter.by_ref() { + if (self.predicate)(&x) { + return Some(x); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Filter + where P: FnMut(&I::Item) -> bool, +{ + #[inline] + fn next_back(&mut self) -> Option { + for x in self.iter.by_ref().rev() { + if (self.predicate)(&x) { + return Some(x); + } + } + None + } +} + +/// An iterator that uses `f` to both filter and map elements from `iter`. +/// +/// This `struct` is created by the [`filter_map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`filter_map()`]: trait.Iterator.html#method.filter_map +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct FilterMap { + iter: I, + f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for FilterMap { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("FilterMap") + .field("iter", &self.iter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for FilterMap + where F: FnMut(I::Item) -> Option, +{ + type Item = B; + + #[inline] + fn next(&mut self) -> Option { + for x in self.iter.by_ref() { + if let Some(y) = (self.f)(x) { + return Some(y); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for FilterMap + where F: FnMut(I::Item) -> Option, +{ + #[inline] + fn next_back(&mut self) -> Option { + for x in self.iter.by_ref().rev() { + if let Some(y) = (self.f)(x) { + return Some(y); + } + } + None + } +} + +/// An iterator that yields the current count and the element during iteration. +/// +/// This `struct` is created by the [`enumerate()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`enumerate()`]: trait.Iterator.html#method.enumerate +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Enumerate { + iter: I, + count: usize, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Enumerate where I: Iterator { + type Item = (usize, ::Item); + + /// # Overflow Behavior + /// + /// The method does no guarding against overflows, so enumerating more than + /// `usize::MAX` elements either produces the wrong result or panics. If + /// debug assertions are enabled, a panic is guaranteed. + /// + /// # Panics + /// + /// Might panic if the index of the element overflows a `usize`. + #[inline] + fn next(&mut self) -> Option<(usize, ::Item)> { + self.iter.next().map(|a| { + let ret = (self.count, a); + // Possible undefined overflow. + self.count += 1; + ret + }) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option<(usize, I::Item)> { + self.iter.nth(n).map(|a| { + let i = self.count + n; + self.count = i + 1; + (i, a) + }) + } + + #[inline] + fn count(self) -> usize { + self.iter.count() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Enumerate where + I: ExactSizeIterator + DoubleEndedIterator +{ + #[inline] + fn next_back(&mut self) -> Option<(usize, ::Item)> { + self.iter.next_back().map(|a| { + let len = self.iter.len(); + // Can safely add, `ExactSizeIterator` promises that the number of + // elements fits into a `usize`. + (self.count + len, a) + }) + } +} + +/// An iterator with a `peek()` that returns an optional reference to the next +/// element. +/// +/// This `struct` is created by the [`peekable()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`peekable()`]: trait.Iterator.html#method.peekable +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Peekable { + iter: I, + peeked: Option, +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Peekable { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + match self.peeked { + Some(_) => self.peeked.take(), + None => self.iter.next(), + } + } + + #[inline] + fn count(self) -> usize { + (if self.peeked.is_some() { 1 } else { 0 }) + self.iter.count() + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + match self.peeked { + Some(_) if n == 0 => self.peeked.take(), + Some(_) => { + self.peeked = None; + self.iter.nth(n-1) + }, + None => self.iter.nth(n) + } + } + + #[inline] + fn last(self) -> Option { + self.iter.last().or(self.peeked) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (lo, hi) = self.iter.size_hint(); + if self.peeked.is_some() { + let lo = lo.saturating_add(1); + let hi = hi.and_then(|x| x.checked_add(1)); + (lo, hi) + } else { + (lo, hi) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Peekable {} + +impl Peekable { + /// Returns a reference to the next() value without advancing the iterator. + /// + /// The `peek()` method will return the value that a call to [`next()`] would + /// return, but does not advance the iterator. Like [`next()`], if there is + /// a value, it's wrapped in a `Some(T)`, but if the iterator is over, it + /// will return `None`. + /// + /// [`next()`]: trait.Iterator.html#tymethod.next + /// + /// Because `peek()` returns reference, and many iterators iterate over + /// references, this leads to a possibly confusing situation where the + /// return value is a double reference. You can see this effect in the + /// examples below, with `&&i32`. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let xs = [1, 2, 3]; + /// + /// let mut iter = xs.iter().peekable(); + /// + /// // peek() lets us see into the future + /// assert_eq!(iter.peek(), Some(&&1)); + /// assert_eq!(iter.next(), Some(&1)); + /// + /// assert_eq!(iter.next(), Some(&2)); + /// + /// // we can peek() multiple times, the iterator won't advance + /// assert_eq!(iter.peek(), Some(&&3)); + /// assert_eq!(iter.peek(), Some(&&3)); + /// + /// assert_eq!(iter.next(), Some(&3)); + /// + /// // after the iterator is finished, so is peek() + /// assert_eq!(iter.peek(), None); + /// assert_eq!(iter.next(), None); + /// ``` + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + pub fn peek(&mut self) -> Option<&I::Item> { + if self.peeked.is_none() { + self.peeked = self.iter.next(); + } + match self.peeked { + Some(ref value) => Some(value), + None => None, + } + } + + /// Checks if the iterator has finished iterating. + /// + /// Returns `true` if there are no more elements in the iterator, and + /// `false` if there are. + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// #![feature(peekable_is_empty)] + /// + /// let xs = [1, 2, 3]; + /// + /// let mut iter = xs.iter().peekable(); + /// + /// // there are still elements to iterate over + /// assert_eq!(iter.is_empty(), false); + /// + /// // let's consume the iterator + /// iter.next(); + /// iter.next(); + /// iter.next(); + /// + /// assert_eq!(iter.is_empty(), true); + /// ``` + #[unstable(feature = "peekable_is_empty", issue = "32111")] + #[inline] + pub fn is_empty(&mut self) -> bool { + self.peek().is_none() + } +} + +/// An iterator that rejects elements while `predicate` is true. +/// +/// This `struct` is created by the [`skip_while()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`skip_while()`]: trait.Iterator.html#method.skip_while +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct SkipWhile { + iter: I, + flag: bool, + predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for SkipWhile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("SkipWhile") + .field("iter", &self.iter) + .field("flag", &self.flag) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for SkipWhile + where P: FnMut(&I::Item) -> bool +{ + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + for x in self.iter.by_ref() { + if self.flag || !(self.predicate)(&x) { + self.flag = true; + return Some(x); + } + } + None + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +/// An iterator that only accepts elements while `predicate` is true. +/// +/// This `struct` is created by the [`take_while()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`take_while()`]: trait.Iterator.html#method.take_while +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct TakeWhile { + iter: I, + flag: bool, + predicate: P, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for TakeWhile { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("TakeWhile") + .field("iter", &self.iter) + .field("flag", &self.flag) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for TakeWhile + where P: FnMut(&I::Item) -> bool +{ + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.flag { + None + } else { + self.iter.next().and_then(|x| { + if (self.predicate)(&x) { + Some(x) + } else { + self.flag = true; + None + } + }) + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the predicate + } +} + +/// An iterator that skips over `n` elements of `iter`. +/// +/// This `struct` is created by the [`skip()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`skip()`]: trait.Iterator.html#method.skip +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Skip { + iter: I, + n: usize +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Skip where I: Iterator { + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option { + if self.n == 0 { + self.iter.next() + } else { + let old_n = self.n; + self.n = 0; + self.iter.nth(old_n) + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + // Can't just add n + self.n due to overflow. + if self.n == 0 { + self.iter.nth(n) + } else { + let to_skip = self.n; + self.n = 0; + // nth(n) skips n+1 + if self.iter.nth(to_skip-1).is_none() { + return None; + } + self.iter.nth(n) + } + } + + #[inline] + fn count(self) -> usize { + self.iter.count().saturating_sub(self.n) + } + + #[inline] + fn last(mut self) -> Option { + if self.n == 0 { + self.iter.last() + } else { + let next = self.next(); + if next.is_some() { + // recurse. n should be 0. + self.last().or(next) + } else { + None + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (lower, upper) = self.iter.size_hint(); + + let lower = lower.saturating_sub(self.n); + let upper = upper.map(|x| x.saturating_sub(self.n)); + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Skip where I: ExactSizeIterator {} + +#[stable(feature = "double_ended_skip_iterator", since = "1.8.0")] +impl DoubleEndedIterator for Skip where I: DoubleEndedIterator + ExactSizeIterator { + fn next_back(&mut self) -> Option { + if self.len() > 0 { + self.iter.next_back() + } else { + None + } + } +} + +/// An iterator that only iterates over the first `n` iterations of `iter`. +/// +/// This `struct` is created by the [`take()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`take()`]: trait.Iterator.html#method.take +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Take { + iter: I, + n: usize +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Take where I: Iterator{ + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option<::Item> { + if self.n != 0 { + self.n -= 1; + self.iter.next() + } else { + None + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + if self.n > n { + self.n -= n + 1; + self.iter.nth(n) + } else { + if self.n > 0 { + self.iter.nth(self.n - 1); + self.n = 0; + } + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (lower, upper) = self.iter.size_hint(); + + let lower = cmp::min(lower, self.n); + + let upper = match upper { + Some(x) if x < self.n => Some(x), + _ => Some(self.n) + }; + + (lower, upper) + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Take where I: ExactSizeIterator {} + + +/// An iterator to maintain state while iterating another iterator. +/// +/// This `struct` is created by the [`scan()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`scan()`]: trait.Iterator.html#method.scan +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Scan { + iter: I, + f: F, + state: St, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Scan { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Scan") + .field("iter", &self.iter) + .field("state", &self.state) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Scan where + I: Iterator, + F: FnMut(&mut St, I::Item) -> Option, +{ + type Item = B; + + #[inline] + fn next(&mut self) -> Option { + self.iter.next().and_then(|a| (self.f)(&mut self.state, a)) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (_, upper) = self.iter.size_hint(); + (0, upper) // can't know a lower bound, due to the scan function + } +} + +/// An iterator that maps each element to an iterator, and yields the elements +/// of the produced iterators. +/// +/// This `struct` is created by the [`flat_map()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`flat_map()`]: trait.Iterator.html#method.flat_map +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct FlatMap { + iter: I, + f: F, + frontiter: Option, + backiter: Option, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for FlatMap + where U::IntoIter: fmt::Debug +{ + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("FlatMap") + .field("iter", &self.iter) + .field("frontiter", &self.frontiter) + .field("backiter", &self.backiter) + .finish() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for FlatMap + where F: FnMut(I::Item) -> U, +{ + type Item = U::Item; + + #[inline] + fn next(&mut self) -> Option { + loop { + if let Some(ref mut inner) = self.frontiter { + if let Some(x) = inner.by_ref().next() { + return Some(x) + } + } + match self.iter.next().map(&mut self.f) { + None => return self.backiter.as_mut().and_then(|it| it.next()), + next => self.frontiter = next.map(IntoIterator::into_iter), + } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let (flo, fhi) = self.frontiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); + let (blo, bhi) = self.backiter.as_ref().map_or((0, Some(0)), |it| it.size_hint()); + let lo = flo.saturating_add(blo); + match (self.iter.size_hint(), fhi, bhi) { + ((0, Some(0)), Some(a), Some(b)) => (lo, a.checked_add(b)), + _ => (lo, None) + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for FlatMap where + F: FnMut(I::Item) -> U, + U: IntoIterator, + U::IntoIter: DoubleEndedIterator +{ + #[inline] + fn next_back(&mut self) -> Option { + loop { + if let Some(ref mut inner) = self.backiter { + if let Some(y) = inner.next_back() { + return Some(y) + } + } + match self.iter.next_back().map(&mut self.f) { + None => return self.frontiter.as_mut().and_then(|it| it.next_back()), + next => self.backiter = next.map(IntoIterator::into_iter), + } + } + } +} + +/// An iterator that yields `None` forever after the underlying iterator +/// yields `None` once. +/// +/// This `struct` is created by the [`fuse()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`fuse()`]: trait.Iterator.html#method.fuse +/// [`Iterator`]: trait.Iterator.html +#[derive(Clone, Debug)] +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Fuse { + iter: I, + done: bool +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Fuse where I: Iterator { + type Item = ::Item; + + #[inline] + fn next(&mut self) -> Option<::Item> { + if self.done { + None + } else { + let next = self.iter.next(); + self.done = next.is_none(); + next + } + } + + #[inline] + fn nth(&mut self, n: usize) -> Option { + if self.done { + None + } else { + let nth = self.iter.nth(n); + self.done = nth.is_none(); + nth + } + } + + #[inline] + fn last(self) -> Option { + if self.done { + None + } else { + self.iter.last() + } + } + + #[inline] + fn count(self) -> usize { + if self.done { + 0 + } else { + self.iter.count() + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + if self.done { + (0, Some(0)) + } else { + self.iter.size_hint() + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Fuse where I: DoubleEndedIterator { + #[inline] + fn next_back(&mut self) -> Option<::Item> { + if self.done { + None + } else { + let next = self.iter.next_back(); + self.done = next.is_none(); + next + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Fuse where I: ExactSizeIterator {} + +/// An iterator that calls a function with a reference to each element before +/// yielding it. +/// +/// This `struct` is created by the [`inspect()`] method on [`Iterator`]. See its +/// documentation for more. +/// +/// [`inspect()`]: trait.Iterator.html#method.inspect +/// [`Iterator`]: trait.Iterator.html +#[must_use = "iterator adaptors are lazy and do nothing unless consumed"] +#[stable(feature = "rust1", since = "1.0.0")] +#[derive(Clone)] +pub struct Inspect { + iter: I, + f: F, +} + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Inspect { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_struct("Inspect") + .field("iter", &self.iter) + .finish() + } +} + +impl Inspect where F: FnMut(&I::Item) { + #[inline] + fn do_inspect(&mut self, elt: Option) -> Option { + if let Some(ref a) = elt { + (self.f)(a); + } + + elt + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Inspect where F: FnMut(&I::Item) { + type Item = I::Item; + + #[inline] + fn next(&mut self) -> Option { + let next = self.iter.next(); + self.do_inspect(next) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + self.iter.size_hint() + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Inspect + where F: FnMut(&I::Item), +{ + #[inline] + fn next_back(&mut self) -> Option { + let next = self.iter.next_back(); + self.do_inspect(next) + } +} diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs new file mode 100644 index 00000000000..08143567bea --- /dev/null +++ b/src/libcore/iter/range.rs @@ -0,0 +1,548 @@ +// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use clone::Clone; +use cmp::PartialOrd; +use mem; +use num::{Zero, One}; +use ops::{self, Add, Sub}; +use option::Option::{self, Some, None}; +use marker::Sized; +use usize; + +use super::{DoubleEndedIterator, ExactSizeIterator, Iterator}; + +/// Objects that can be stepped over in both directions. +/// +/// The `steps_between` function provides a way to efficiently compare +/// two `Step` objects. +#[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] +pub trait Step: PartialOrd + Sized { + /// Steps `self` if possible. + fn step(&self, by: &Self) -> Option; + + /// Returns the number of steps between two step objects. The count is + /// inclusive of `start` and exclusive of `end`. + /// + /// Returns `None` if it is not possible to calculate `steps_between` + /// without overflow. + fn steps_between(start: &Self, end: &Self, by: &Self) -> Option; +} + +macro_rules! step_impl_unsigned { + ($($t:ty)*) => ($( + #[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] + impl Step for $t { + #[inline] + fn step(&self, by: &$t) -> Option<$t> { + (*self).checked_add(*by) + } + #[inline] + #[allow(trivial_numeric_casts)] + fn steps_between(start: &$t, end: &$t, by: &$t) -> Option { + if *by == 0 { return None; } + if *start < *end { + // Note: We assume $t <= usize here + let diff = (*end - *start) as usize; + let by = *by as usize; + if diff % by > 0 { + Some(diff / by + 1) + } else { + Some(diff / by) + } + } else { + Some(0) + } + } + } + )*) +} +macro_rules! step_impl_signed { + ($($t:ty)*) => ($( + #[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] + impl Step for $t { + #[inline] + fn step(&self, by: &$t) -> Option<$t> { + (*self).checked_add(*by) + } + #[inline] + #[allow(trivial_numeric_casts)] + fn steps_between(start: &$t, end: &$t, by: &$t) -> Option { + if *by == 0 { return None; } + let diff: usize; + let by_u: usize; + if *by > 0 { + if *start >= *end { + return Some(0); + } + // Note: We assume $t <= isize here + // Use .wrapping_sub and cast to usize to compute the + // difference that may not fit inside the range of isize. + diff = (*end as isize).wrapping_sub(*start as isize) as usize; + by_u = *by as usize; + } else { + if *start <= *end { + return Some(0); + } + diff = (*start as isize).wrapping_sub(*end as isize) as usize; + by_u = (*by as isize).wrapping_mul(-1) as usize; + } + if diff % by_u > 0 { + Some(diff / by_u + 1) + } else { + Some(diff / by_u) + } + } + } + )*) +} + +macro_rules! step_impl_no_between { + ($($t:ty)*) => ($( + #[unstable(feature = "step_trait", + reason = "likely to be replaced by finer-grained traits", + issue = "27741")] + impl Step for $t { + #[inline] + fn step(&self, by: &$t) -> Option<$t> { + (*self).checked_add(*by) + } + #[inline] + fn steps_between(_a: &$t, _b: &$t, _by: &$t) -> Option { + None + } + } + )*) +} + +step_impl_unsigned!(usize u8 u16 u32); +step_impl_signed!(isize i8 i16 i32); +#[cfg(target_pointer_width = "64")] +step_impl_unsigned!(u64); +#[cfg(target_pointer_width = "64")] +step_impl_signed!(i64); +// If the target pointer width is not 64-bits, we +// assume here that it is less than 64-bits. +#[cfg(not(target_pointer_width = "64"))] +step_impl_no_between!(u64 i64); + +/// An adapter for stepping range iterators by a custom amount. +/// +/// The resulting iterator handles overflow by stopping. The `A` +/// parameter is the type being iterated over, while `R` is the range +/// type (usually one of `std::ops::{Range, RangeFrom, RangeInclusive}`. +#[derive(Clone, Debug)] +#[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] +pub struct StepBy { + step_by: A, + range: R, +} + +impl ops::RangeFrom { + /// Creates an iterator starting at the same point, but stepping by + /// the given amount at each iteration. + /// + /// # Examples + /// + /// ``` + /// # #![feature(step_by)] + /// + /// for i in (0u8..).step_by(2).take(10) { + /// println!("{}", i); + /// } + /// ``` + /// + /// This prints the first ten even natural integers (0 to 18). + #[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] + pub fn step_by(self, by: A) -> StepBy { + StepBy { + step_by: by, + range: self + } + } +} + +impl ops::Range { + /// Creates an iterator with the same range, but stepping by the + /// given amount at each iteration. + /// + /// The resulting iterator handles overflow by stopping. + /// + /// # Examples + /// + /// ``` + /// #![feature(step_by)] + /// + /// for i in (0..10).step_by(2) { + /// println!("{}", i); + /// } + /// ``` + /// + /// This prints: + /// + /// ```text + /// 0 + /// 2 + /// 4 + /// 6 + /// 8 + /// ``` + #[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] + pub fn step_by(self, by: A) -> StepBy { + StepBy { + step_by: by, + range: self + } + } +} + +impl ops::RangeInclusive { + /// Creates an iterator with the same range, but stepping by the + /// given amount at each iteration. + /// + /// The resulting iterator handles overflow by stopping. + /// + /// # Examples + /// + /// ``` + /// #![feature(step_by, inclusive_range_syntax)] + /// + /// for i in (0...10).step_by(2) { + /// println!("{}", i); + /// } + /// ``` + /// + /// This prints: + /// + /// ```text + /// 0 + /// 2 + /// 4 + /// 6 + /// 8 + /// 10 + /// ``` + #[unstable(feature = "step_by", reason = "recent addition", + issue = "27741")] + pub fn step_by(self, by: A) -> StepBy { + StepBy { + step_by: by, + range: self + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for StepBy> where + A: Clone, + for<'a> &'a A: Add<&'a A, Output = A> +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + let mut n = &self.range.start + &self.step_by; + mem::swap(&mut n, &mut self.range.start); + Some(n) + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + (usize::MAX, None) // Too bad we can't specify an infinite lower bound + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for StepBy> { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + let rev = self.step_by < A::zero(); + if (rev && self.range.start > self.range.end) || + (!rev && self.range.start < self.range.end) + { + match self.range.start.step(&self.step_by) { + Some(mut n) => { + mem::swap(&mut self.range.start, &mut n); + Some(n) + }, + None => { + let mut n = self.range.end.clone(); + mem::swap(&mut self.range.start, &mut n); + Some(n) + } + } + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + match Step::steps_between(&self.range.start, + &self.range.end, + &self.step_by) { + Some(hint) => (hint, Some(hint)), + None => (0, None) + } + } +} + +#[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] +impl Iterator for StepBy> { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + use ops::RangeInclusive::*; + + // this function has a sort of odd structure due to borrowck issues + // we may need to replace self.range, so borrows of start and end need to end early + + let (finishing, n) = match self.range { + Empty { .. } => return None, // empty iterators yield no values + + NonEmpty { ref mut start, ref mut end } => { + let zero = A::zero(); + let rev = self.step_by < zero; + + // march start towards (maybe past!) end and yield the old value + if (rev && start >= end) || + (!rev && start <= end) + { + match start.step(&self.step_by) { + Some(mut n) => { + mem::swap(start, &mut n); + (None, Some(n)) // yield old value, remain non-empty + }, + None => { + let mut n = end.clone(); + mem::swap(start, &mut n); + (None, Some(n)) // yield old value, remain non-empty + } + } + } else { + // found range in inconsistent state (start at or past end), so become empty + (Some(mem::replace(end, zero)), None) + } + } + }; + + // turn into an empty iterator if we've reached the end + if let Some(end) = finishing { + self.range = Empty { at: end }; + } + + n + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + use ops::RangeInclusive::*; + + match self.range { + Empty { .. } => (0, Some(0)), + + NonEmpty { ref start, ref end } => + match Step::steps_between(start, + end, + &self.step_by) { + Some(hint) => (hint.saturating_add(1), hint.checked_add(1)), + None => (0, None) + } + } + } +} + +macro_rules! range_exact_iter_impl { + ($($t:ty)*) => ($( + #[stable(feature = "rust1", since = "1.0.0")] + impl ExactSizeIterator for ops::Range<$t> { } + + #[unstable(feature = "inclusive_range", + reason = "recently added, follows RFC", + issue = "28237")] + impl ExactSizeIterator for ops::RangeInclusive<$t> { } + )*) +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for ops::Range where + for<'a> &'a A: Add<&'a A, Output = A> +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + if self.start < self.end { + let mut n = &self.start + &A::one(); + mem::swap(&mut n, &mut self.start); + Some(n) + } else { + None + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + match Step::steps_between(&self.start, &self.end, &A::one()) { + Some(hint) => (hint, Some(hint)), + None => (0, None) + } + } +} + +// Ranges of u64 and i64 are excluded because they cannot guarantee having +// a length <= usize::MAX, which is required by ExactSizeIterator. +range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32); + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for ops::Range where + for<'a> &'a A: Add<&'a A, Output = A>, + for<'a> &'a A: Sub<&'a A, Output = A> +{ + #[inline] + fn next_back(&mut self) -> Option { + if self.start < self.end { + self.end = &self.end - &A::one(); + Some(self.end.clone()) + } else { + None + } + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for ops::RangeFrom where + for<'a> &'a A: Add<&'a A, Output = A> +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + let mut n = &self.start + &A::one(); + mem::swap(&mut n, &mut self.start); + Some(n) + } +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl Iterator for ops::RangeInclusive where + for<'a> &'a A: Add<&'a A, Output = A> +{ + type Item = A; + + #[inline] + fn next(&mut self) -> Option { + use ops::RangeInclusive::*; + + // this function has a sort of odd structure due to borrowck issues + // we may need to replace self, so borrows of self.start and self.end need to end early + + let (finishing, n) = match *self { + Empty { .. } => (None, None), // empty iterators yield no values + + NonEmpty { ref mut start, ref mut end } => { + if start == end { + (Some(mem::replace(end, A::one())), Some(mem::replace(start, A::one()))) + } else if start < end { + let one = A::one(); + let mut n = &*start + &one; + mem::swap(&mut n, start); + + // if the iterator is done iterating, it will change from NonEmpty to Empty + // to avoid unnecessary drops or clones, we'll reuse either start or end + // (they are equal now, so it doesn't matter which) + // to pull out end, we need to swap something back in -- use the previously + // created A::one() as a dummy value + + (if n == *end { Some(mem::replace(end, one)) } else { None }, + // ^ are we done yet? + Some(n)) // < the value to output + } else { + (Some(mem::replace(start, A::one())), None) + } + } + }; + + // turn into an empty iterator if this is the last value + if let Some(end) = finishing { + *self = Empty { at: end }; + } + + n + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + use ops::RangeInclusive::*; + + match *self { + Empty { .. } => (0, Some(0)), + + NonEmpty { ref start, ref end } => + match Step::steps_between(start, end, &A::one()) { + Some(hint) => (hint.saturating_add(1), hint.checked_add(1)), + None => (0, None), + } + } + } +} + +#[unstable(feature = "inclusive_range", reason = "recently added, follows RFC", issue = "28237")] +impl DoubleEndedIterator for ops::RangeInclusive where + for<'a> &'a A: Add<&'a A, Output = A>, + for<'a> &'a A: Sub<&'a A, Output = A> +{ + #[inline] + fn next_back(&mut self) -> Option { + use ops::RangeInclusive::*; + + // see Iterator::next for comments + + let (finishing, n) = match *self { + Empty { .. } => return None, + + NonEmpty { ref mut start, ref mut end } => { + if start == end { + (Some(mem::replace(start, A::one())), Some(mem::replace(end, A::one()))) + } else if start < end { + let one = A::one(); + let mut n = &*end - &one; + mem::swap(&mut n, end); + + (if n == *start { Some(mem::replace(start, one)) } else { None }, + Some(n)) + } else { + (Some(mem::replace(end, A::one())), None) + } + } + }; + + if let Some(start) = finishing { + *self = Empty { at: start }; + } + + n + } +} + diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs new file mode 100644 index 00000000000..ecd4a78b9e7 --- /dev/null +++ b/src/libcore/iter/sources.rs @@ -0,0 +1,270 @@ +// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use clone::Clone; +use default::Default; +use fmt; +use marker; +use option::Option::{self, Some, None}; +use usize; + +use super::{DoubleEndedIterator, IntoIterator, Iterator, ExactSizeIterator}; + +/// An iterator that repeats an element endlessly. +/// +/// This `struct` is created by the [`repeat()`] function. See its documentation for more. +/// +/// [`repeat()`]: fn.repeat.html +#[derive(Clone, Debug)] +#[stable(feature = "rust1", since = "1.0.0")] +pub struct Repeat { + element: A +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl Iterator for Repeat { + type Item = A; + + #[inline] + fn next(&mut self) -> Option { Some(self.element.clone()) } + #[inline] + fn size_hint(&self) -> (usize, Option) { (usize::MAX, None) } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl DoubleEndedIterator for Repeat { + #[inline] + fn next_back(&mut self) -> Option { Some(self.element.clone()) } +} + +/// Creates a new iterator that endlessly repeats a single element. +/// +/// The `repeat()` function repeats a single value over and over and over and +/// over and over and 🔁. +/// +/// Infinite iterators like `repeat()` are often used with adapters like +/// [`take()`], in order to make them finite. +/// +/// [`take()`]: trait.Iterator.html#method.take +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // the number four 4ever: +/// let mut fours = iter::repeat(4); +/// +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// assert_eq!(Some(4), fours.next()); +/// +/// // yup, still four +/// assert_eq!(Some(4), fours.next()); +/// ``` +/// +/// Going finite with [`take()`]: +/// +/// ``` +/// use std::iter; +/// +/// // that last example was too many fours. Let's only have four fours. +/// let mut four_fours = iter::repeat(4).take(4); +/// +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// assert_eq!(Some(4), four_fours.next()); +/// +/// // ... and now we're done +/// assert_eq!(None, four_fours.next()); +/// ``` +#[inline] +#[stable(feature = "rust1", since = "1.0.0")] +pub fn repeat(elt: T) -> Repeat { + Repeat{element: elt} +} + +/// An iterator that yields nothing. +/// +/// This `struct` is created by the [`empty()`] function. See its documentation for more. +/// +/// [`empty()`]: fn.empty.html +#[stable(feature = "iter_empty", since = "1.2.0")] +pub struct Empty(marker::PhantomData); + +#[stable(feature = "core_impl_debug", since = "1.9.0")] +impl fmt::Debug for Empty { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad("Empty") + } +} + +#[stable(feature = "iter_empty", since = "1.2.0")] +impl Iterator for Empty { + type Item = T; + + fn next(&mut self) -> Option { + None + } + + fn size_hint(&self) -> (usize, Option){ + (0, Some(0)) + } +} + +#[stable(feature = "iter_empty", since = "1.2.0")] +impl DoubleEndedIterator for Empty { + fn next_back(&mut self) -> Option { + None + } +} + +#[stable(feature = "iter_empty", since = "1.2.0")] +impl ExactSizeIterator for Empty { + fn len(&self) -> usize { + 0 + } +} + +// not #[derive] because that adds a Clone bound on T, +// which isn't necessary. +#[stable(feature = "iter_empty", since = "1.2.0")] +impl Clone for Empty { + fn clone(&self) -> Empty { + Empty(marker::PhantomData) + } +} + +// not #[derive] because that adds a Default bound on T, +// which isn't necessary. +#[stable(feature = "iter_empty", since = "1.2.0")] +impl Default for Empty { + fn default() -> Empty { + Empty(marker::PhantomData) + } +} + +/// Creates an iterator that yields nothing. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // this could have been an iterator over i32, but alas, it's just not. +/// let mut nope = iter::empty::(); +/// +/// assert_eq!(None, nope.next()); +/// ``` +#[stable(feature = "iter_empty", since = "1.2.0")] +pub fn empty() -> Empty { + Empty(marker::PhantomData) +} + +/// An iterator that yields an element exactly once. +/// +/// This `struct` is created by the [`once()`] function. See its documentation for more. +/// +/// [`once()`]: fn.once.html +#[derive(Clone, Debug)] +#[stable(feature = "iter_once", since = "1.2.0")] +pub struct Once { + inner: ::option::IntoIter +} + +#[stable(feature = "iter_once", since = "1.2.0")] +impl Iterator for Once { + type Item = T; + + fn next(&mut self) -> Option { + self.inner.next() + } + + fn size_hint(&self) -> (usize, Option) { + self.inner.size_hint() + } +} + +#[stable(feature = "iter_once", since = "1.2.0")] +impl DoubleEndedIterator for Once { + fn next_back(&mut self) -> Option { + self.inner.next_back() + } +} + +#[stable(feature = "iter_once", since = "1.2.0")] +impl ExactSizeIterator for Once { + fn len(&self) -> usize { + self.inner.len() + } +} + +/// Creates an iterator that yields an element exactly once. +/// +/// This is commonly used to adapt a single value into a [`chain()`] of other +/// kinds of iteration. Maybe you have an iterator that covers almost +/// everything, but you need an extra special case. Maybe you have a function +/// which works on iterators, but you only need to process one value. +/// +/// [`chain()`]: trait.Iterator.html#method.chain +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter; +/// +/// // one is the loneliest number +/// let mut one = iter::once(1); +/// +/// assert_eq!(Some(1), one.next()); +/// +/// // just one, that's all we get +/// assert_eq!(None, one.next()); +/// ``` +/// +/// Chaining together with another iterator. Let's say that we want to iterate +/// over each file of the `.foo` directory, but also a configuration file, +/// `.foorc`: +/// +/// ```no_run +/// use std::iter; +/// use std::fs; +/// use std::path::PathBuf; +/// +/// let dirs = fs::read_dir(".foo").unwrap(); +/// +/// // we need to convert from an iterator of DirEntry-s to an iterator of +/// // PathBufs, so we use map +/// let dirs = dirs.map(|file| file.unwrap().path()); +/// +/// // now, our iterator just for our config file +/// let config = iter::once(PathBuf::from(".foorc")); +/// +/// // chain the two iterators together into one big iterator +/// let files = dirs.chain(config); +/// +/// // this will give us all of the files in .foo as well as .foorc +/// for f in files { +/// println!("{:?}", f); +/// } +/// ``` +#[stable(feature = "iter_once", since = "1.2.0")] +pub fn once(value: T) -> Once { + Once { inner: Some(value).into_iter() } +} diff --git a/src/libcore/iter/traits.rs b/src/libcore/iter/traits.rs new file mode 100644 index 00000000000..67503984450 --- /dev/null +++ b/src/libcore/iter/traits.rs @@ -0,0 +1,526 @@ +// Copyright 2013-2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use option::Option::{self, Some}; +use marker::Sized; + +use super::Iterator; + +/// Conversion from an `Iterator`. +/// +/// By implementing `FromIterator` for a type, you define how it will be +/// created from an iterator. This is common for types which describe a +/// collection of some kind. +/// +/// `FromIterator`'s [`from_iter()`] is rarely called explicitly, and is instead +/// used through [`Iterator`]'s [`collect()`] method. See [`collect()`]'s +/// documentation for more examples. +/// +/// [`from_iter()`]: #tymethod.from_iter +/// [`Iterator`]: trait.Iterator.html +/// [`collect()`]: trait.Iterator.html#method.collect +/// +/// See also: [`IntoIterator`]. +/// +/// [`IntoIterator`]: trait.IntoIterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// use std::iter::FromIterator; +/// +/// let five_fives = std::iter::repeat(5).take(5); +/// +/// let v = Vec::from_iter(five_fives); +/// +/// assert_eq!(v, vec![5, 5, 5, 5, 5]); +/// ``` +/// +/// Using [`collect()`] to implicitly use `FromIterator`: +/// +/// ``` +/// let five_fives = std::iter::repeat(5).take(5); +/// +/// let v: Vec = five_fives.collect(); +/// +/// assert_eq!(v, vec![5, 5, 5, 5, 5]); +/// ``` +/// +/// Implementing `FromIterator` for your type: +/// +/// ``` +/// use std::iter::FromIterator; +/// +/// // A sample collection, that's just a wrapper over Vec +/// #[derive(Debug)] +/// struct MyCollection(Vec); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // and we'll implement FromIterator +/// impl FromIterator for MyCollection { +/// fn from_iter>(iter: I) -> Self { +/// let mut c = MyCollection::new(); +/// +/// for i in iter { +/// c.add(i); +/// } +/// +/// c +/// } +/// } +/// +/// // Now we can make a new iterator... +/// let iter = (0..5).into_iter(); +/// +/// // ... and make a MyCollection out of it +/// let c = MyCollection::from_iter(iter); +/// +/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); +/// +/// // collect works too! +/// +/// let iter = (0..5).into_iter(); +/// let c: MyCollection = iter.collect(); +/// +/// assert_eq!(c.0, vec![0, 1, 2, 3, 4]); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +#[rustc_on_unimplemented="a collection of type `{Self}` cannot be \ + built from an iterator over elements of type `{A}`"] +pub trait FromIterator: Sized { + /// Creates a value from an iterator. + /// + /// See the [module-level documentation] for more. + /// + /// [module-level documentation]: trait.FromIterator.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// use std::iter::FromIterator; + /// + /// let five_fives = std::iter::repeat(5).take(5); + /// + /// let v = Vec::from_iter(five_fives); + /// + /// assert_eq!(v, vec![5, 5, 5, 5, 5]); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn from_iter>(iter: T) -> Self; +} + +/// Conversion into an `Iterator`. +/// +/// By implementing `IntoIterator` for a type, you define how it will be +/// converted to an iterator. This is common for types which describe a +/// collection of some kind. +/// +/// One benefit of implementing `IntoIterator` is that your type will [work +/// with Rust's `for` loop syntax](index.html#for-loops-and-intoiterator). +/// +/// See also: [`FromIterator`]. +/// +/// [`FromIterator`]: trait.FromIterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// let v = vec![1, 2, 3]; +/// +/// let mut iter = v.into_iter(); +/// +/// let n = iter.next(); +/// assert_eq!(Some(1), n); +/// +/// let n = iter.next(); +/// assert_eq!(Some(2), n); +/// +/// let n = iter.next(); +/// assert_eq!(Some(3), n); +/// +/// let n = iter.next(); +/// assert_eq!(None, n); +/// ``` +/// +/// Implementing `IntoIterator` for your type: +/// +/// ``` +/// // A sample collection, that's just a wrapper over Vec +/// #[derive(Debug)] +/// struct MyCollection(Vec); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // and we'll implement IntoIterator +/// impl IntoIterator for MyCollection { +/// type Item = i32; +/// type IntoIter = ::std::vec::IntoIter; +/// +/// fn into_iter(self) -> Self::IntoIter { +/// self.0.into_iter() +/// } +/// } +/// +/// // Now we can make a new collection... +/// let mut c = MyCollection::new(); +/// +/// // ... add some stuff to it ... +/// c.add(0); +/// c.add(1); +/// c.add(2); +/// +/// // ... and then turn it into an Iterator: +/// for (i, n) in c.into_iter().enumerate() { +/// assert_eq!(i as i32, n); +/// } +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait IntoIterator { + /// The type of the elements being iterated over. + #[stable(feature = "rust1", since = "1.0.0")] + type Item; + + /// Which kind of iterator are we turning this into? + #[stable(feature = "rust1", since = "1.0.0")] + type IntoIter: Iterator; + + /// Creates an iterator from a value. + /// + /// See the [module-level documentation] for more. + /// + /// [module-level documentation]: trait.IntoIterator.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let v = vec![1, 2, 3]; + /// + /// let mut iter = v.into_iter(); + /// + /// let n = iter.next(); + /// assert_eq!(Some(1), n); + /// + /// let n = iter.next(); + /// assert_eq!(Some(2), n); + /// + /// let n = iter.next(); + /// assert_eq!(Some(3), n); + /// + /// let n = iter.next(); + /// assert_eq!(None, n); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn into_iter(self) -> Self::IntoIter; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl IntoIterator for I { + type Item = I::Item; + type IntoIter = I; + + fn into_iter(self) -> I { + self + } +} + +/// Extend a collection with the contents of an iterator. +/// +/// Iterators produce a series of values, and collections can also be thought +/// of as a series of values. The `Extend` trait bridges this gap, allowing you +/// to extend a collection by including the contents of that iterator. +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // You can extend a String with some chars: +/// let mut message = String::from("The first three letters are: "); +/// +/// message.extend(&['a', 'b', 'c']); +/// +/// assert_eq!("abc", &message[29..32]); +/// ``` +/// +/// Implementing `Extend`: +/// +/// ``` +/// // A sample collection, that's just a wrapper over Vec +/// #[derive(Debug)] +/// struct MyCollection(Vec); +/// +/// // Let's give it some methods so we can create one and add things +/// // to it. +/// impl MyCollection { +/// fn new() -> MyCollection { +/// MyCollection(Vec::new()) +/// } +/// +/// fn add(&mut self, elem: i32) { +/// self.0.push(elem); +/// } +/// } +/// +/// // since MyCollection has a list of i32s, we implement Extend for i32 +/// impl Extend for MyCollection { +/// +/// // This is a bit simpler with the concrete type signature: we can call +/// // extend on anything which can be turned into an Iterator which gives +/// // us i32s. Because we need i32s to put into MyCollection. +/// fn extend>(&mut self, iter: T) { +/// +/// // The implementation is very straightforward: loop through the +/// // iterator, and add() each element to ourselves. +/// for elem in iter { +/// self.add(elem); +/// } +/// } +/// } +/// +/// let mut c = MyCollection::new(); +/// +/// c.add(5); +/// c.add(6); +/// c.add(7); +/// +/// // let's extend our collection with three more numbers +/// c.extend(vec![1, 2, 3]); +/// +/// // we've added these elements onto the end +/// assert_eq!("MyCollection([5, 6, 7, 1, 2, 3])", format!("{:?}", c)); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait Extend { + /// Extends a collection with the contents of an iterator. + /// + /// As this is the only method for this trait, the [trait-level] docs + /// contain more details. + /// + /// [trait-level]: trait.Extend.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // You can extend a String with some chars: + /// let mut message = String::from("abc"); + /// + /// message.extend(['d', 'e', 'f'].iter()); + /// + /// assert_eq!("abcdef", &message); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn extend>(&mut self, iter: T); +} + +/// An iterator able to yield elements from both ends. +/// +/// Something that implements `DoubleEndedIterator` has one extra capability +/// over something that implements [`Iterator`]: the ability to also take +/// `Item`s from the back, as well as the front. +/// +/// It is important to note that both back and forth work on the same range, +/// and do not cross: iteration is over when they meet in the middle. +/// +/// In a similar fashion to the [`Iterator`] protocol, once a +/// `DoubleEndedIterator` returns `None` from a `next_back()`, calling it again +/// may or may not ever return `Some` again. `next()` and `next_back()` are +/// interchangable for this purpose. +/// +/// [`Iterator`]: trait.Iterator.html +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// let numbers = vec![1, 2, 3]; +/// +/// let mut iter = numbers.iter(); +/// +/// assert_eq!(Some(&1), iter.next()); +/// assert_eq!(Some(&3), iter.next_back()); +/// assert_eq!(Some(&2), iter.next_back()); +/// assert_eq!(None, iter.next()); +/// assert_eq!(None, iter.next_back()); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait DoubleEndedIterator: Iterator { + /// An iterator able to yield elements from both ends. + /// + /// As this is the only method for this trait, the [trait-level] docs + /// contain more details. + /// + /// [trait-level]: trait.DoubleEndedIterator.html + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// let numbers = vec![1, 2, 3]; + /// + /// let mut iter = numbers.iter(); + /// + /// assert_eq!(Some(&1), iter.next()); + /// assert_eq!(Some(&3), iter.next_back()); + /// assert_eq!(Some(&2), iter.next_back()); + /// assert_eq!(None, iter.next()); + /// assert_eq!(None, iter.next_back()); + /// ``` + #[stable(feature = "rust1", since = "1.0.0")] + fn next_back(&mut self) -> Option; +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I: DoubleEndedIterator + ?Sized> DoubleEndedIterator for &'a mut I { + fn next_back(&mut self) -> Option { (**self).next_back() } +} + +/// An iterator that knows its exact length. +/// +/// Many [`Iterator`]s don't know how many times they will iterate, but some do. +/// If an iterator knows how many times it can iterate, providing access to +/// that information can be useful. For example, if you want to iterate +/// backwards, a good start is to know where the end is. +/// +/// When implementing an `ExactSizeIterator`, You must also implement +/// [`Iterator`]. When doing so, the implementation of [`size_hint()`] *must* +/// return the exact size of the iterator. +/// +/// [`Iterator`]: trait.Iterator.html +/// [`size_hint()`]: trait.Iterator.html#method.size_hint +/// +/// The [`len()`] method has a default implementation, so you usually shouldn't +/// implement it. However, you may be able to provide a more performant +/// implementation than the default, so overriding it in this case makes sense. +/// +/// [`len()`]: #method.len +/// +/// # Examples +/// +/// Basic usage: +/// +/// ``` +/// // a finite range knows exactly how many times it will iterate +/// let five = 0..5; +/// +/// assert_eq!(5, five.len()); +/// ``` +/// +/// In the [module level docs][moddocs], we implemented an [`Iterator`], +/// `Counter`. Let's implement `ExactSizeIterator` for it as well: +/// +/// [moddocs]: index.html +/// +/// ``` +/// # struct Counter { +/// # count: usize, +/// # } +/// # impl Counter { +/// # fn new() -> Counter { +/// # Counter { count: 0 } +/// # } +/// # } +/// # impl Iterator for Counter { +/// # type Item = usize; +/// # fn next(&mut self) -> Option { +/// # self.count += 1; +/// # if self.count < 6 { +/// # Some(self.count) +/// # } else { +/// # None +/// # } +/// # } +/// # } +/// impl ExactSizeIterator for Counter { +/// // We already have the number of iterations, so we can use it directly. +/// fn len(&self) -> usize { +/// self.count +/// } +/// } +/// +/// // And now we can use it! +/// +/// let counter = Counter::new(); +/// +/// assert_eq!(0, counter.len()); +/// ``` +#[stable(feature = "rust1", since = "1.0.0")] +pub trait ExactSizeIterator: Iterator { + #[inline] + #[stable(feature = "rust1", since = "1.0.0")] + /// Returns the exact number of times the iterator will iterate. + /// + /// This method has a default implementation, so you usually should not + /// implement it directly. However, if you can provide a more efficient + /// implementation, you can do so. See the [trait-level] docs for an + /// example. + /// + /// This function has the same safety guarantees as the [`size_hint()`] + /// function. + /// + /// [trait-level]: trait.ExactSizeIterator.html + /// [`size_hint()`]: trait.Iterator.html#method.size_hint + /// + /// # Examples + /// + /// Basic usage: + /// + /// ``` + /// // a finite range knows exactly how many times it will iterate + /// let five = 0..5; + /// + /// assert_eq!(5, five.len()); + /// ``` + fn len(&self) -> usize { + let (lower, upper) = self.size_hint(); + // Note: This assertion is overly defensive, but it checks the invariant + // guaranteed by the trait. If this trait were rust-internal, + // we could use debug_assert!; assert_eq! will check all Rust user + // implementations too. + assert_eq!(upper, Some(lower)); + lower + } +} + +#[stable(feature = "rust1", since = "1.0.0")] +impl<'a, I: ExactSizeIterator + ?Sized> ExactSizeIterator for &'a mut I {} + From 085fddac50a808d2013a86b5ae11297cd31adcb3 Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Mon, 18 Apr 2016 20:21:08 +0200 Subject: [PATCH 04/15] core::iter: break long lines --- src/libcore/iter/iterator.rs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs index 0cc83d42ce0..d130a0b873c 100644 --- a/src/libcore/iter/iterator.rs +++ b/src/libcore/iter/iterator.rs @@ -17,9 +17,12 @@ use ops::{Add, FnMut, Mul}; use option::Option::{self, Some, None}; use marker::Sized; -use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse, Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev, Zip}; +use super::{Chain, Cycle, Cloned, Enumerate, Filter, FilterMap, FlatMap, Fuse, + Inspect, Map, Peekable, Scan, Skip, SkipWhile, Take, TakeWhile, Rev, + Zip}; use super::ChainState; -use super::{DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, IntoIterator}; +use super::{DoubleEndedIterator, ExactSizeIterator, Extend, FromIterator, + IntoIterator}; fn _assert_is_object_safe(_: &Iterator) {} From 1cd8d1e2b95e95d4fb7e3340d174532d1aee9d7c Mon Sep 17 00:00:00 2001 From: Ulrik Sverdrup Date: Mon, 18 Apr 2016 23:44:02 +0200 Subject: [PATCH 05/15] core::iter: Move ExactSizeIterator impls to each struct definition --- src/libcore/iter/mod.rs | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs index 8449ee78501..abc199cd182 100644 --- a/src/libcore/iter/mod.rs +++ b/src/libcore/iter/mod.rs @@ -333,25 +333,6 @@ mod range; mod sources; mod traits; -// All adaptors that preserve the size of the wrapped iterator are fine -// Adaptors that may overflow in `size_hint` are not, i.e. `Chain`. -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Enumerate where I: ExactSizeIterator {} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Inspect where - F: FnMut(&I::Item), -{} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Rev - where I: ExactSizeIterator + DoubleEndedIterator {} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Map where - F: FnMut(I::Item) -> B, -{} -#[stable(feature = "rust1", since = "1.0.0")] -impl ExactSizeIterator for Zip - where A: ExactSizeIterator, B: ExactSizeIterator {} - /// An double-ended iterator with the direction inverted. /// /// This `struct` is created by the [`rev()`] method on [`Iterator`]. See its @@ -382,6 +363,10 @@ impl DoubleEndedIterator for Rev where I: DoubleEndedIterator { fn next_back(&mut self) -> Option<::Item> { self.iter.next() } } +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Rev + where I: ExactSizeIterator + DoubleEndedIterator {} + /// An iterator that clones the elements of an underlying iterator. /// /// This `struct` is created by the [`cloned()`] method on [`Iterator`]. See its @@ -679,6 +664,10 @@ impl DoubleEndedIterator for Zip where } } +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Zip + where A: ExactSizeIterator, B: ExactSizeIterator {} + /// An iterator that maps the values of `iter` with `f`. /// /// This `struct` is created by the [`map()`] method on [`Iterator`]. See its @@ -771,6 +760,10 @@ impl DoubleEndedIterator for Map where } } +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Map + where F: FnMut(I::Item) -> B {} + /// An iterator that filters the elements of `iter` with `predicate`. /// /// This `struct` is created by the [`filter()`] method on [`Iterator`]. See its @@ -966,6 +959,9 @@ impl DoubleEndedIterator for Enumerate where } } +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Enumerate where I: ExactSizeIterator {} + /// An iterator with a `peek()` that returns an optional reference to the next /// element. /// @@ -1655,3 +1651,7 @@ impl DoubleEndedIterator for Inspect self.do_inspect(next) } } + +#[stable(feature = "rust1", since = "1.0.0")] +impl ExactSizeIterator for Inspect + where F: FnMut(&I::Item) {} From d1180afbd99d533802f57f8c1fbf8c2723831ef2 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Wed, 20 Apr 2016 00:13:30 +0300 Subject: [PATCH 06/15] Generate block containing return lazily instead --- src/librustc/mir/repr.rs | 7 ---- src/librustc_mir/build/expr/into.rs | 3 +- src/librustc_mir/build/mod.rs | 50 ++++++++++++++++++----------- src/librustc_mir/lib.rs | 1 - 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/repr.rs index 67cd28c30e6..d5c321ffa6a 100644 --- a/src/librustc/mir/repr.rs +++ b/src/librustc/mir/repr.rs @@ -213,13 +213,6 @@ impl BasicBlock { BasicBlock(index as u32) } - /// Returns a BasicBlock with index 1. This is actual end block (containing - /// the Return terminator) only during the building of MIR and should not be - /// used outside that. - pub const fn end_block() -> BasicBlock { - BasicBlock(1) - } - /// Extract the index. pub fn index(self) -> usize { self.0 as usize diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs index 976d13fca29..fe32f1de0c5 100644 --- a/src/librustc_mir/build/expr/into.rs +++ b/src/librustc_mir/build/expr/into.rs @@ -262,7 +262,8 @@ impl<'a,'tcx> Builder<'a,'tcx> { } }; let extent = this.extent_of_return_scope(); - this.exit_scope(expr_span, extent, block, BasicBlock::end_block()); + let return_block = this.return_block(); + this.exit_scope(expr_span, extent, block, return_block); this.cfg.start_new_block().unit() } ExprKind::Call { ty, fun, args } => { diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index a92d686b85d..82916f08999 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -24,23 +24,23 @@ pub struct Builder<'a, 'tcx: 'a> { fn_span: Span, - // the current set of scopes, updated as we traverse; - // see the `scope` module for more details + /// the current set of scopes, updated as we traverse; + /// see the `scope` module for more details scopes: Vec>, - // for each scope, a span of blocks that defines it; - // we track these for use in region and borrow checking, - // but these are liable to get out of date once optimization - // begins. They are also hopefully temporary, and will be - // no longer needed when we adopt graph-based regions. + /// for each scope, a span of blocks that defines it; + /// we track these for use in region and borrow checking, + /// but these are liable to get out of date once optimization + /// begins. They are also hopefully temporary, and will be + /// no longer needed when we adopt graph-based regions. scope_auxiliary: ScopeAuxiliaryVec, - // the current set of loops; see the `scope` module for more - // details + /// the current set of loops; see the `scope` module for more + /// details loop_scopes: Vec, - // the vector of all scopes that we have created thus far; - // we track this for debuginfo later + /// the vector of all scopes that we have created thus far; + /// we track this for debuginfo later scope_datas: Vec, var_decls: Vec>, @@ -48,9 +48,11 @@ pub struct Builder<'a, 'tcx: 'a> { temp_decls: Vec>, unit_temp: Option>, - // cached block with a RESUME terminator; we create this at the - // first panic + /// cached block with the RESUME terminator; this is created + /// when first set of cleanups are built. cached_resume_block: Option, + /// cached block with the RETURN terminator + cached_return_block: Option, } struct CFG<'tcx> { @@ -180,12 +182,10 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>, var_indices: FnvHashMap(), unit_temp: None, cached_resume_block: None, + cached_return_block: None }; assert_eq!(builder.cfg.start_new_block(), START_BLOCK); - let end_block = builder.cfg.start_new_block(); - assert_eq!(end_block, BasicBlock::end_block()); - let mut arg_decls = None; // assigned to `Some` in closures below let call_site_extent = @@ -205,11 +205,12 @@ pub fn construct<'a,'tcx>(hir: Cx<'a,'tcx>, block.unit() })); + let return_block = builder.return_block(); builder.cfg.terminate(block, call_site_scope_id, span, - TerminatorKind::Goto { target: end_block }); - builder.cfg.terminate(end_block, call_site_scope_id, span, + TerminatorKind::Goto { target: return_block }); + builder.cfg.terminate(return_block, call_site_scope_id, span, TerminatorKind::Return); - end_block.unit() + return_block.unit() }); assert!( @@ -290,6 +291,17 @@ impl<'a,'tcx> Builder<'a,'tcx> { } } } + + fn return_block(&mut self) -> BasicBlock { + match self.cached_return_block { + Some(rb) => rb, + None => { + let rb = self.cfg.start_new_block(); + self.cached_return_block = Some(rb); + rb + } + } + } } /////////////////////////////////////////////////////////////////////////// diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 78d3f4f6207..ced73f34e0d 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -21,7 +21,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![unstable(feature = "rustc_private", issue = "27812")] #![feature(box_patterns)] -#![feature(const_fn)] #![feature(rustc_private)] #![feature(staged_api)] #![feature(question_mark)] From c99b73a767a38d5b97214b7dbf6ee3c08ac782fd Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 7 Apr 2016 18:16:12 +1200 Subject: [PATCH 07/15] Trivial refactoring --- src/librustc_driver/driver.rs | 14 +++++++------- src/librustc_metadata/creader.rs | 17 ++++++++--------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index de1a740e0bb..9c444fca9a1 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -766,12 +766,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, "external crate/lib resolution", || LocalCrateReader::new(sess, cstore, &hir_map, name).read_crates()); - let lang_items = time(time_passes, "language item collection", || { - sess.track_errors(|| { - middle::lang_items::collect_language_items(&sess, &hir_map) - }) - })?; - let resolve::CrateMap { def_map, freevars, @@ -779,9 +773,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, trait_map, glob_map, } = time(time_passes, - "resolution", + "name resolution", || resolve::resolve_crate(sess, &hir_map, make_glob_map)); + let lang_items = time(time_passes, "language item collection", || { + sess.track_errors(|| { + middle::lang_items::collect_language_items(&sess, &hir_map) + }) + })?; + let mut analysis = ty::CrateAnalysis { export_map: export_map, access_levels: AccessLevels::default(), diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index df9072835b9..8ec238f4b24 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -813,9 +813,8 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { fn process_crate(&self, c: &hir::Crate) { for a in c.attrs.iter().filter(|m| m.name() == "link_args") { - match a.value_str() { - Some(ref linkarg) => self.cstore.add_used_link_args(&linkarg), - None => { /* fallthrough */ } + if let Some(ref linkarg) = a.value_str() { + self.cstore.add_used_link_args(&linkarg); } } } @@ -830,12 +829,12 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { match self.creader.extract_crate_info_hir(i) { Some(info) => { let (cnum, _, _) = self.creader.resolve_crate(&None, - &info.ident, - &info.name, - None, - i.span, - PathKind::Crate, - true); + &info.ident, + &info.name, + None, + i.span, + PathKind::Crate, + true); let def_id = self.ast_map.local_def_id(i.id); let len = self.ast_map.def_path(def_id).data.len(); From f61b40446777f9ef9b32c19d8df24ded855fd082 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 11:55:34 +1200 Subject: [PATCH 08/15] Split up NodeCollector so that defs are collected separately from nodes for the HIR map. --- src/librustc/hir/map/collector.rs | 335 ++++++++++++++++++++---------- src/librustc/hir/map/mod.rs | 38 ++-- src/librustc_driver/driver.rs | 37 ++-- 3 files changed, 269 insertions(+), 141 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 95f9e8eaac2..7f6a587fade 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -19,25 +19,28 @@ use std::iter::repeat; use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; use syntax::codemap::Span; -/// A Visitor that walks over an AST and collects Node's into an AST -/// Map. +/// A Visitor that walks over the HIR and collects Node's into a HIR map. pub struct NodeCollector<'ast> { pub krate: &'ast Crate, pub map: Vec>, - pub definitions: Definitions, pub parent_node: NodeId, } -impl<'ast> NodeCollector<'ast> { - pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { - let mut collector = NodeCollector { - krate: krate, - map: vec![], - definitions: Definitions::new(), - parent_node: CRATE_NODE_ID, - }; - collector.insert_entry(CRATE_NODE_ID, RootCrate); +pub struct DefCollector<'ast> { + pub krate: &'ast Crate, + pub map: &'ast [MapEntry<'ast>], + pub definitions: Definitions, + pub parent_def: Option, +} +impl<'ast> DefCollector<'ast> { + pub fn root(krate: &'ast Crate, map: &'ast [MapEntry<'ast>]) -> DefCollector<'ast> { + let mut collector = DefCollector { + krate: krate, + map: map, + definitions: Definitions::new(), + parent_def: None, + }; let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); assert_eq!(result, CRATE_DEF_INDEX); @@ -47,17 +50,16 @@ impl<'ast> NodeCollector<'ast> { } pub fn extend(krate: &'ast Crate, - parent: &'ast InlinedItem, parent_node: NodeId, parent_def_path: DefPath, parent_def_id: DefId, - map: Vec>, + map: &'ast [MapEntry<'ast>], definitions: Definitions) - -> NodeCollector<'ast> { - let mut collector = NodeCollector { + -> DefCollector<'ast> { + let mut collector = DefCollector { krate: krate, map: map, - parent_node: parent_node, + parent_def: None, definitions: definitions, }; @@ -67,21 +69,14 @@ impl<'ast> NodeCollector<'ast> { def_id: parent_def_id, }); - collector.insert_entry(parent_node, RootInlinedParent(parent)); - collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); + let def = collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); + collector.parent_def = Some(def); collector } fn parent_def(&self) -> Option { - let mut parent_node = Some(self.parent_node); - while let Some(p) = parent_node { - if let Some(q) = self.definitions.opt_def_index(p) { - return Some(q); - } - parent_node = self.map[p as usize].parent_node(); - } - None + self.parent_def } fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { @@ -97,28 +92,9 @@ impl<'ast> NodeCollector<'ast> { -> DefIndex { self.definitions.create_def_with_parent(parent, node_id, data) } - - fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) { - debug!("ast_map: {:?} => {:?}", id, entry); - let len = self.map.len(); - if id as usize >= len { - self.map.extend(repeat(NotPresent).take(id as usize - len + 1)); - } - self.map[id as usize] = entry; - } - - fn insert_def(&mut self, id: NodeId, node: Node<'ast>, data: DefPathData) -> DefIndex { - self.insert(id, node); - self.create_def(id, data) - } - - fn insert(&mut self, id: NodeId, node: Node<'ast>) { - let entry = MapEntry::from_node(self.parent_node, node); - self.insert_entry(id, entry); - } } -impl<'ast> Visitor<'ast> for NodeCollector<'ast> { +impl<'ast> Visitor<'ast> for DefCollector<'ast> { /// Because we want to track parent items and so forth, enable /// deep walking so that we walk nested items in the context of /// their outer items. @@ -146,18 +122,16 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { DefPathData::Misc, }; - self.insert_def(i.id, NodeItem(i), def_data); + let def = self.create_def(i.id, def_data); - let parent_node = self.parent_node; - self.parent_node = i.id; + let parent_def = self.parent_def; + self.parent_def = Some(def); match i.node { - ItemImpl(..) => {} ItemEnum(ref enum_definition, _) => { for v in &enum_definition.variants { let variant_def_index = - self.insert_def(v.node.data.id(), - NodeVariant(v), + self.create_def(v.node.data.id(), DefPathData::EnumVariant(v.node.name)); for field in v.node.data.fields() { @@ -168,13 +142,10 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } } } - ItemForeignMod(..) => { - } ItemStruct(ref struct_def, _) => { // If this is a tuple-like struct, register the constructor. if !struct_def.is_struct() { - self.insert_def(struct_def.id(), - NodeStructCtor(struct_def), + self.create_def(struct_def.id(), DefPathData::StructCtor); } @@ -182,6 +153,196 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.create_def(field.id, DefPathData::Field(field.name)); } } + _ => {} + } + intravisit::walk_item(self, i); + self.parent_def = parent_def; + } + + fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { + let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + intravisit::walk_foreign_item(self, foreign_item); + self.parent_def = parent_def; + } + + fn visit_generics(&mut self, generics: &'ast Generics) { + for ty_param in generics.ty_params.iter() { + self.create_def(ty_param.id, + DefPathData::TypeParam(ty_param.name)); + } + + intravisit::walk_generics(self, generics); + } + + fn visit_trait_item(&mut self, ti: &'ast TraitItem) { + let def_data = match ti.node { + MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), + TypeTraitItem(..) => DefPathData::TypeNs(ti.name), + }; + + let def = self.create_def(ti.id, def_data); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + + match ti.node { + ConstTraitItem(_, Some(ref expr)) => { + self.create_def(expr.id, DefPathData::Initializer); + } + _ => { } + } + + intravisit::walk_trait_item(self, ti); + + self.parent_def = parent_def; + } + + fn visit_impl_item(&mut self, ii: &'ast ImplItem) { + let def_data = match ii.node { + ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), + ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), + }; + + let def = self.create_def(ii.id, def_data); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + + match ii.node { + ImplItemKind::Const(_, ref expr) => { + self.create_def(expr.id, DefPathData::Initializer); + } + _ => { } + } + + intravisit::walk_impl_item(self, ii); + + self.parent_def = parent_def; + } + + fn visit_pat(&mut self, pat: &'ast Pat) { + let maybe_binding = match pat.node { + PatKind::Ident(_, id, _) => Some(id.node), + _ => None + }; + + let parent_def = self.parent_def; + if let Some(id) = maybe_binding { + let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + self.parent_def = Some(def); + } + + intravisit::walk_pat(self, pat); + self.parent_def = parent_def; + } + + fn visit_expr(&mut self, expr: &'ast Expr) { + let parent_def = self.parent_def; + + if let ExprClosure(..) = expr.node { + let def = self.create_def(expr.id, DefPathData::ClosureExpr); + self.parent_def = Some(def); + } + + intravisit::walk_expr(self, expr); + self.parent_def = parent_def; + } + + fn visit_stmt(&mut self, stmt: &'ast Stmt) { + intravisit::walk_stmt(self, stmt); + } + + fn visit_block(&mut self, block: &'ast Block) { + intravisit::walk_block(self, block); + } + + fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { + self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); + } + + fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + } +} + +impl<'ast> NodeCollector<'ast> { + pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { + let mut collector = NodeCollector { + krate: krate, + map: vec![], + parent_node: CRATE_NODE_ID, + }; + collector.insert_entry(CRATE_NODE_ID, RootCrate); + + collector + } + + pub fn extend(krate: &'ast Crate, + parent: &'ast InlinedItem, + parent_node: NodeId, + parent_def_path: DefPath, + parent_def_id: DefId, + map: Vec>) + -> NodeCollector<'ast> { + let mut collector = NodeCollector { + krate: krate, + map: map, + parent_node: parent_node, + }; + + assert_eq!(parent_def_path.krate, parent_def_id.krate); + collector.insert_entry(parent_node, RootInlinedParent(parent)); + + collector + } + + fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) { + debug!("ast_map: {:?} => {:?}", id, entry); + let len = self.map.len(); + if id as usize >= len { + self.map.extend(repeat(NotPresent).take(id as usize - len + 1)); + } + self.map[id as usize] = entry; + } + + fn insert(&mut self, id: NodeId, node: Node<'ast>) { + let entry = MapEntry::from_node(self.parent_node, node); + self.insert_entry(id, entry); + } +} + +impl<'ast> Visitor<'ast> for NodeCollector<'ast> { + /// Because we want to track parent items and so forth, enable + /// deep walking so that we walk nested items in the context of + /// their outer items. + fn visit_nested_item(&mut self, item: ItemId) { + debug!("visit_nested_item: {:?}", item); + self.visit_item(self.krate.item(item.id)) + } + + fn visit_item(&mut self, i: &'ast Item) { + debug!("visit_item: {:?}", i); + + self.insert(i.id, NodeItem(i)); + + let parent_node = self.parent_node; + self.parent_node = i.id; + + match i.node { + ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + self.insert(v.node.data.id(), NodeVariant(v)); + } + } + ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + self.insert(struct_def.id(), NodeStructCtor(struct_def)); + } + } ItemTrait(_, _, ref bounds, _) => { for b in bounds.iter() { if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { @@ -206,9 +367,7 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - self.insert_def(foreign_item.id, - NodeForeignItem(foreign_item), - DefPathData::ValueNs(foreign_item.name)); + self.insert(foreign_item.id, NodeForeignItem(foreign_item)); let parent_node = self.parent_node; self.parent_node = foreign_item.id; @@ -218,72 +377,36 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_generics(&mut self, generics: &'ast Generics) { for ty_param in generics.ty_params.iter() { - self.insert_def(ty_param.id, - NodeTyParam(ty_param), - DefPathData::TypeParam(ty_param.name)); + self.insert(ty_param.id, NodeTyParam(ty_param)); } intravisit::walk_generics(self, generics); } fn visit_trait_item(&mut self, ti: &'ast TraitItem) { - let def_data = match ti.node { - MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), - TypeTraitItem(..) => DefPathData::TypeNs(ti.name), - }; - self.insert(ti.id, NodeTraitItem(ti)); - self.create_def(ti.id, def_data); let parent_node = self.parent_node; self.parent_node = ti.id; - match ti.node { - ConstTraitItem(_, Some(ref expr)) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - intravisit::walk_trait_item(self, ti); self.parent_node = parent_node; } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { - let def_data = match ii.node { - ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), - ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), - }; - - self.insert_def(ii.id, NodeImplItem(ii), def_data); + self.insert(ii.id, NodeImplItem(ii)); let parent_node = self.parent_node; self.parent_node = ii.id; - match ii.node { - ImplItemKind::Const(_, ref expr) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - intravisit::walk_impl_item(self, ii); self.parent_node = parent_node; } fn visit_pat(&mut self, pat: &'ast Pat) { - let maybe_binding = match pat.node { - PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - - if let Some(id) = maybe_binding { - self.insert_def(pat.id, NodeLocal(pat), DefPathData::Binding(id.name)); - } else { - self.insert(pat.id, NodePat(pat)); - } + self.insert(pat.id, NodeLocal(pat)); let parent_node = self.parent_node; self.parent_node = pat.id; @@ -294,11 +417,6 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_expr(&mut self, expr: &'ast Expr) { self.insert(expr.id, NodeExpr(expr)); - match expr.node { - ExprClosure(..) => { self.create_def(expr.id, DefPathData::ClosureExpr); } - _ => { } - } - let parent_node = self.parent_node; self.parent_node = expr.id; intravisit::walk_expr(self, expr); @@ -331,13 +449,4 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { self.insert(lifetime.id, NodeLifetime(lifetime)); } - - fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { - self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); - self.visit_lifetime(&def.lifetime); - } - - fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { - self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); - } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 7b8ddee0e23..6331f7d3009 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -10,7 +10,7 @@ pub use self::Node::*; use self::MapEntry::*; -use self::collector::NodeCollector; +use self::collector::{NodeCollector, DefCollector}; pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData, InlinedRootPath}; @@ -784,7 +784,14 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { let (map, definitions) = { let mut collector = NodeCollector::root(&forest.krate); intravisit::walk_crate(&mut collector, &forest.krate); - (collector.map, collector.definitions) + + let definitions = { + let mut def_collector = DefCollector::root(&forest.krate, &collector.map); + intravisit::walk_crate(&mut def_collector, &forest.krate); + def_collector.definitions + }; + + (collector.map, definitions) }; if log_enabled!(::log::DEBUG) { @@ -836,19 +843,26 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii = map.forest.inlined_items.alloc(ii); let ii_parent_id = fld.new_id(DUMMY_NODE_ID); - let mut collector = - NodeCollector::extend( - map.krate(), - ii, - ii_parent_id, - parent_def_path, - parent_def_id, - mem::replace(&mut *map.map.borrow_mut(), vec![]), - mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); + let mut collector = NodeCollector::extend(map.krate(), + ii, + ii_parent_id, + parent_def_path.clone(), + parent_def_id, + mem::replace(&mut *map.map.borrow_mut(), vec![])); ii.visit(&mut collector); + { + let mut def_collector = DefCollector::extend(map.krate(), + ii_parent_id, + parent_def_path, + parent_def_id, + &collector.map, + mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); + ii.visit(&mut def_collector); + *map.definitions.borrow_mut() = def_collector.definitions; + } + *map.map.borrow_mut() = collector.map; - *map.definitions.borrow_mut() = collector.definitions; ii } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 9c444fca9a1..c211fa2925e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -120,6 +120,27 @@ pub fn compile_input(sess: &Session, Ok(())); let expanded_crate = assign_node_ids(sess, expanded_crate); + let dep_graph = DepGraph::new(sess.opts.build_dep_graph); + + // TODO + // time(sess.time_passes(), + // "external crate/lib resolution", + // || LocalCrateReader::new(sess, &cstore, &defs, &id).read_crates()); + + // TODO + panic!(); + + // TODO CrateMap result + // let resolve::CrateMap { + // def_map, + // freevars, + // export_map, + // trait_map, + // glob_map, + // } = time(sess.time_passes(), + // "name resolution", + // || resolve::resolve_crate(sess, &hir_map, control.make_glob_map)); + // Lower ast -> hir. let lcx = LoweringContext::new(sess, Some(&expanded_crate)); let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); @@ -175,7 +196,6 @@ pub fn compile_input(sess: &Session, hir_map, &arenas, &id, - control.make_glob_map, |tcx, mir_map, analysis, result| { { // Eventually, we will want to track plugins. @@ -743,7 +763,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, hir_map: hir_map::Map<'tcx>, arenas: &'tcx ty::CtxtArenas<'tcx>, name: &str, - make_glob_map: resolve::MakeGlobMap, f: F) -> Result where F: FnOnce(&TyCtxt<'tcx>, Option>, ty::CrateAnalysis, CompileResult) -> R @@ -762,20 +781,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, let time_passes = sess.time_passes(); - time(time_passes, - "external crate/lib resolution", - || LocalCrateReader::new(sess, cstore, &hir_map, name).read_crates()); - - let resolve::CrateMap { - def_map, - freevars, - export_map, - trait_map, - glob_map, - } = time(time_passes, - "name resolution", - || resolve::resolve_crate(sess, &hir_map, make_glob_map)); - let lang_items = time(time_passes, "language item collection", || { sess.track_errors(|| { middle::lang_items::collect_language_items(&sess, &hir_map) From d6bcc04c521bcdf82b7727ec35e3f6ce0cbb5b0f Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 12:14:03 +1200 Subject: [PATCH 09/15] Move DefCollector to its own module. --- src/librustc/hir/map/collector.rs | 248 +------------------------ src/librustc/hir/map/def_collector.rs | 258 ++++++++++++++++++++++++++ src/librustc/hir/map/mod.rs | 7 +- src/librustc_driver/driver.rs | 2 +- 4 files changed, 267 insertions(+), 248 deletions(-) create mode 100644 src/librustc/hir/map/def_collector.rs diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 7f6a587fade..d7fccf03aec 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -1,4 +1,4 @@ -// Copyright 2015 The Rust Project Developers. See the COPYRIGHT +// Copyright 2015-2016 The Rust Project Developers. See the COPYRIGHT // file at the top-level directory of this distribution and at // http://rust-lang.org/COPYRIGHT. // @@ -13,10 +13,10 @@ use super::MapEntry::*; use hir::*; use hir::intravisit::Visitor; -use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use hir::def_id::DefId; use middle::cstore::InlinedItem; use std::iter::repeat; -use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; +use syntax::ast::{NodeId, CRATE_NODE_ID}; use syntax::codemap::Span; /// A Visitor that walks over the HIR and collects Node's into a HIR map. @@ -26,248 +26,6 @@ pub struct NodeCollector<'ast> { pub parent_node: NodeId, } -pub struct DefCollector<'ast> { - pub krate: &'ast Crate, - pub map: &'ast [MapEntry<'ast>], - pub definitions: Definitions, - pub parent_def: Option, -} - -impl<'ast> DefCollector<'ast> { - pub fn root(krate: &'ast Crate, map: &'ast [MapEntry<'ast>]) -> DefCollector<'ast> { - let mut collector = DefCollector { - krate: krate, - map: map, - definitions: Definitions::new(), - parent_def: None, - }; - let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); - assert_eq!(result, CRATE_DEF_INDEX); - - collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); - - collector - } - - pub fn extend(krate: &'ast Crate, - parent_node: NodeId, - parent_def_path: DefPath, - parent_def_id: DefId, - map: &'ast [MapEntry<'ast>], - definitions: Definitions) - -> DefCollector<'ast> { - let mut collector = DefCollector { - krate: krate, - map: map, - parent_def: None, - definitions: definitions, - }; - - assert_eq!(parent_def_path.krate, parent_def_id.krate); - let root_path = Box::new(InlinedRootPath { - data: parent_def_path.data, - def_id: parent_def_id, - }); - - let def = collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); - collector.parent_def = Some(def); - - collector - } - - fn parent_def(&self) -> Option { - self.parent_def - } - - fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { - let parent_def = self.parent_def(); - debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); - self.definitions.create_def_with_parent(parent_def, node_id, data) - } - - fn create_def_with_parent(&mut self, - parent: Option, - node_id: NodeId, - data: DefPathData) - -> DefIndex { - self.definitions.create_def_with_parent(parent, node_id, data) - } -} - -impl<'ast> Visitor<'ast> for DefCollector<'ast> { - /// Because we want to track parent items and so forth, enable - /// deep walking so that we walk nested items in the context of - /// their outer items. - fn visit_nested_item(&mut self, item: ItemId) { - debug!("visit_nested_item: {:?}", item); - self.visit_item(self.krate.item(item.id)) - } - - fn visit_item(&mut self, i: &'ast Item) { - debug!("visit_item: {:?}", i); - - // Pick the def data. This need not be unique, but the more - // information we encapsulate into - let def_data = match i.node { - ItemDefaultImpl(..) | ItemImpl(..) => - DefPathData::Impl, - ItemEnum(..) | ItemStruct(..) | ItemTrait(..) | - ItemExternCrate(..) | ItemForeignMod(..) | ItemTy(..) => - DefPathData::TypeNs(i.name), - ItemMod(..) => - DefPathData::Module(i.name), - ItemStatic(..) | ItemConst(..) | ItemFn(..) => - DefPathData::ValueNs(i.name), - ItemUse(..) => - DefPathData::Misc, - }; - - let def = self.create_def(i.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match i.node { - ItemEnum(ref enum_definition, _) => { - for v in &enum_definition.variants { - let variant_def_index = - self.create_def(v.node.data.id(), - DefPathData::EnumVariant(v.node.name)); - - for field in v.node.data.fields() { - self.create_def_with_parent( - Some(variant_def_index), - field.id, - DefPathData::Field(field.name)); - } - } - } - ItemStruct(ref struct_def, _) => { - // If this is a tuple-like struct, register the constructor. - if !struct_def.is_struct() { - self.create_def(struct_def.id(), - DefPathData::StructCtor); - } - - for field in struct_def.fields() { - self.create_def(field.id, DefPathData::Field(field.name)); - } - } - _ => {} - } - intravisit::walk_item(self, i); - self.parent_def = parent_def; - } - - fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - intravisit::walk_foreign_item(self, foreign_item); - self.parent_def = parent_def; - } - - fn visit_generics(&mut self, generics: &'ast Generics) { - for ty_param in generics.ty_params.iter() { - self.create_def(ty_param.id, - DefPathData::TypeParam(ty_param.name)); - } - - intravisit::walk_generics(self, generics); - } - - fn visit_trait_item(&mut self, ti: &'ast TraitItem) { - let def_data = match ti.node { - MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), - TypeTraitItem(..) => DefPathData::TypeNs(ti.name), - }; - - let def = self.create_def(ti.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match ti.node { - ConstTraitItem(_, Some(ref expr)) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - - intravisit::walk_trait_item(self, ti); - - self.parent_def = parent_def; - } - - fn visit_impl_item(&mut self, ii: &'ast ImplItem) { - let def_data = match ii.node { - ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), - ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), - }; - - let def = self.create_def(ii.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match ii.node { - ImplItemKind::Const(_, ref expr) => { - self.create_def(expr.id, DefPathData::Initializer); - } - _ => { } - } - - intravisit::walk_impl_item(self, ii); - - self.parent_def = parent_def; - } - - fn visit_pat(&mut self, pat: &'ast Pat) { - let maybe_binding = match pat.node { - PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - - let parent_def = self.parent_def; - if let Some(id) = maybe_binding { - let def = self.create_def(pat.id, DefPathData::Binding(id.name)); - self.parent_def = Some(def); - } - - intravisit::walk_pat(self, pat); - self.parent_def = parent_def; - } - - fn visit_expr(&mut self, expr: &'ast Expr) { - let parent_def = self.parent_def; - - if let ExprClosure(..) = expr.node { - let def = self.create_def(expr.id, DefPathData::ClosureExpr); - self.parent_def = Some(def); - } - - intravisit::walk_expr(self, expr); - self.parent_def = parent_def; - } - - fn visit_stmt(&mut self, stmt: &'ast Stmt) { - intravisit::walk_stmt(self, stmt); - } - - fn visit_block(&mut self, block: &'ast Block) { - intravisit::walk_block(self, block); - } - - fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { - self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); - } - - fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { - self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); - } -} - impl<'ast> NodeCollector<'ast> { pub fn root(krate: &'ast Crate) -> NodeCollector<'ast> { let mut collector = NodeCollector { diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs new file mode 100644 index 00000000000..0e64a2d676e --- /dev/null +++ b/src/librustc/hir/map/def_collector.rs @@ -0,0 +1,258 @@ +// Copyright 2016 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use super::*; + +use hir::*; +use hir::intravisit::Visitor; +use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; + +/// Creates def ids for nodes in the HIR. +pub struct DefCollector<'ast> { + pub krate: &'ast Crate, + pub map: &'ast [MapEntry<'ast>], + pub definitions: Definitions, + pub parent_def: Option, +} + +impl<'ast> DefCollector<'ast> { + pub fn root(krate: &'ast Crate, map: &'ast [MapEntry<'ast>]) -> DefCollector<'ast> { + let mut collector = DefCollector { + krate: krate, + map: map, + definitions: Definitions::new(), + parent_def: None, + }; + let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); + assert_eq!(result, CRATE_DEF_INDEX); + + collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); + + collector + } + + pub fn extend(krate: &'ast Crate, + parent_node: NodeId, + parent_def_path: DefPath, + parent_def_id: DefId, + map: &'ast [MapEntry<'ast>], + definitions: Definitions) + -> DefCollector<'ast> { + let mut collector = DefCollector { + krate: krate, + map: map, + parent_def: None, + definitions: definitions, + }; + + assert_eq!(parent_def_path.krate, parent_def_id.krate); + let root_path = Box::new(InlinedRootPath { + data: parent_def_path.data, + def_id: parent_def_id, + }); + + let def = collector.create_def(parent_node, DefPathData::InlinedRoot(root_path)); + collector.parent_def = Some(def); + + collector + } + + fn parent_def(&self) -> Option { + self.parent_def + } + + fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex { + let parent_def = self.parent_def(); + debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); + self.definitions.create_def_with_parent(parent_def, node_id, data) + } + + fn create_def_with_parent(&mut self, + parent: Option, + node_id: NodeId, + data: DefPathData) + -> DefIndex { + self.definitions.create_def_with_parent(parent, node_id, data) + } +} + +impl<'ast> Visitor<'ast> for DefCollector<'ast> { + /// Because we want to track parent items and so forth, enable + /// deep walking so that we walk nested items in the context of + /// their outer items. + fn visit_nested_item(&mut self, item: ItemId) { + debug!("visit_nested_item: {:?}", item); + self.visit_item(self.krate.item(item.id)) + } + + fn visit_item(&mut self, i: &'ast Item) { + debug!("visit_item: {:?}", i); + + // Pick the def data. This need not be unique, but the more + // information we encapsulate into + let def_data = match i.node { + ItemDefaultImpl(..) | ItemImpl(..) => + DefPathData::Impl, + ItemEnum(..) | ItemStruct(..) | ItemTrait(..) | + ItemExternCrate(..) | ItemMod(..) | ItemForeignMod(..) | + ItemTy(..) => + DefPathData::TypeNs(i.name), + ItemStatic(..) | ItemConst(..) | ItemFn(..) => + DefPathData::ValueNs(i.name), + ItemUse(..) => + DefPathData::Misc, + }; + + let def = self.create_def(i.id, def_data); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + + match i.node { + ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + let variant_def_index = + self.create_def(v.node.data.id(), + DefPathData::EnumVariant(v.node.name)); + + for field in v.node.data.fields() { + self.create_def_with_parent( + Some(variant_def_index), + field.id, + DefPathData::Field(field.name)); + } + } + } + ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + self.create_def(struct_def.id(), + DefPathData::StructCtor); + } + + for field in struct_def.fields() { + self.create_def(field.id, DefPathData::Field(field.name)); + } + } + _ => {} + } + intravisit::walk_item(self, i); + self.parent_def = parent_def; + } + + fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { + let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + intravisit::walk_foreign_item(self, foreign_item); + self.parent_def = parent_def; + } + + fn visit_generics(&mut self, generics: &'ast Generics) { + for ty_param in generics.ty_params.iter() { + self.create_def(ty_param.id, + DefPathData::TypeParam(ty_param.name)); + } + + intravisit::walk_generics(self, generics); + } + + fn visit_trait_item(&mut self, ti: &'ast TraitItem) { + let def_data = match ti.node { + MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), + TypeTraitItem(..) => DefPathData::TypeNs(ti.name), + }; + + let def = self.create_def(ti.id, def_data); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + + match ti.node { + ConstTraitItem(_, Some(ref expr)) => { + self.create_def(expr.id, DefPathData::Initializer); + } + _ => { } + } + + intravisit::walk_trait_item(self, ti); + + self.parent_def = parent_def; + } + + fn visit_impl_item(&mut self, ii: &'ast ImplItem) { + let def_data = match ii.node { + ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), + ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), + }; + + let def = self.create_def(ii.id, def_data); + + let parent_def = self.parent_def; + self.parent_def = Some(def); + + match ii.node { + ImplItemKind::Const(_, ref expr) => { + self.create_def(expr.id, DefPathData::Initializer); + } + _ => { } + } + + intravisit::walk_impl_item(self, ii); + + self.parent_def = parent_def; + } + + fn visit_pat(&mut self, pat: &'ast Pat) { + let maybe_binding = match pat.node { + PatKind::Ident(_, id, _) => Some(id.node), + _ => None + }; + + let parent_def = self.parent_def; + if let Some(id) = maybe_binding { + let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + self.parent_def = Some(def); + } + + intravisit::walk_pat(self, pat); + self.parent_def = parent_def; + } + + fn visit_expr(&mut self, expr: &'ast Expr) { + let parent_def = self.parent_def; + + if let ExprClosure(..) = expr.node { + let def = self.create_def(expr.id, DefPathData::ClosureExpr); + self.parent_def = Some(def); + } + + intravisit::walk_expr(self, expr); + self.parent_def = parent_def; + } + + fn visit_stmt(&mut self, stmt: &'ast Stmt) { + intravisit::walk_stmt(self, stmt); + } + + fn visit_block(&mut self, block: &'ast Block) { + intravisit::walk_block(self, block); + } + + fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { + self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); + } + + fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + } +} diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 6331f7d3009..d0ec83b7eb3 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -10,7 +10,8 @@ pub use self::Node::*; use self::MapEntry::*; -use self::collector::{NodeCollector, DefCollector}; +use self::collector::NodeCollector; +use self::def_collector::DefCollector; pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData, InlinedRootPath}; @@ -36,6 +37,7 @@ use std::mem; pub mod blocks; mod collector; +mod def_collector; pub mod definitions; #[derive(Copy, Clone, Debug)] @@ -852,12 +854,13 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, ii.visit(&mut collector); { + let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); let mut def_collector = DefCollector::extend(map.krate(), ii_parent_id, parent_def_path, parent_def_id, &collector.map, - mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); + defs); ii.visit(&mut def_collector); *map.definitions.borrow_mut() = def_collector.definitions; } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index c211fa2925e..488e7ae56ef 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -121,7 +121,7 @@ pub fn compile_input(sess: &Session, let expanded_crate = assign_node_ids(sess, expanded_crate); let dep_graph = DepGraph::new(sess.opts.build_dep_graph); - + // TODO // time(sess.time_passes(), // "external crate/lib resolution", From 6af7acab1c6976933c90b07a58450567227b4719 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 12:39:18 +1200 Subject: [PATCH 10/15] Separate def collection and hir map making even further --- src/librustc/hir/map/def_collector.rs | 6 +--- src/librustc/hir/map/mod.rs | 47 ++++++++++++--------------- src/librustc_driver/driver.rs | 20 ++++++------ src/librustc_driver/pretty.rs | 3 +- 4 files changed, 33 insertions(+), 43 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 0e64a2d676e..974791f62bb 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -18,16 +18,14 @@ use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; /// Creates def ids for nodes in the HIR. pub struct DefCollector<'ast> { pub krate: &'ast Crate, - pub map: &'ast [MapEntry<'ast>], pub definitions: Definitions, pub parent_def: Option, } impl<'ast> DefCollector<'ast> { - pub fn root(krate: &'ast Crate, map: &'ast [MapEntry<'ast>]) -> DefCollector<'ast> { + pub fn root(krate: &'ast Crate) -> DefCollector<'ast> { let mut collector = DefCollector { krate: krate, - map: map, definitions: Definitions::new(), parent_def: None, }; @@ -43,12 +41,10 @@ impl<'ast> DefCollector<'ast> { parent_node: NodeId, parent_def_path: DefPath, parent_def_id: DefId, - map: &'ast [MapEntry<'ast>], definitions: Definitions) -> DefCollector<'ast> { let mut collector = DefCollector { krate: krate, - map: map, parent_def: None, definitions: definitions, }; diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d0ec83b7eb3..70071c224f8 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -782,19 +782,16 @@ impl Folder for IdAndSpanUpdater { } } -pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { - let (map, definitions) = { - let mut collector = NodeCollector::root(&forest.krate); - intravisit::walk_crate(&mut collector, &forest.krate); +pub fn collect_definitions<'ast>(forest: &'ast mut Forest) -> Definitions { + let mut def_collector = DefCollector::root(&forest.krate); + intravisit::walk_crate(&mut def_collector, &forest.krate); + def_collector.definitions +} - let definitions = { - let mut def_collector = DefCollector::root(&forest.krate, &collector.map); - intravisit::walk_crate(&mut def_collector, &forest.krate); - def_collector.definitions - }; - - (collector.map, definitions) - }; +pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Map<'ast> { + let mut collector = NodeCollector::root(&forest.krate); + intravisit::walk_crate(&mut collector, &forest.krate); + let map = collector.map; if log_enabled!(::log::DEBUG) { // This only makes sense for ordered stores; note the @@ -843,28 +840,24 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, }; let ii = map.forest.inlined_items.alloc(ii); - let ii_parent_id = fld.new_id(DUMMY_NODE_ID); + + let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); + let mut def_collector = DefCollector::extend(map.krate(), + ii_parent_id, + parent_def_path.clone(), + parent_def_id, + defs); + ii.visit(&mut def_collector); + *map.definitions.borrow_mut() = def_collector.definitions; + let mut collector = NodeCollector::extend(map.krate(), ii, ii_parent_id, - parent_def_path.clone(), + parent_def_path, parent_def_id, mem::replace(&mut *map.map.borrow_mut(), vec![])); ii.visit(&mut collector); - - { - let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); - let mut def_collector = DefCollector::extend(map.krate(), - ii_parent_id, - parent_def_path, - parent_def_id, - &collector.map, - defs); - ii.visit(&mut def_collector); - *map.definitions.borrow_mut() = def_collector.definitions; - } - *map.map.borrow_mut() = collector.map; ii diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 488e7ae56ef..d63cf875632 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -156,7 +156,16 @@ pub fn compile_input(sess: &Session, } let arenas = ty::CtxtArenas::new(); - let hir_map = make_map(sess, &mut hir_forest); + // Collect defintions for def ids. + let defs = time(sess.time_passes(), + "collecting defs", + move || hir_map::collect_defs(hir_forest)); + + // Construct the HIR map + let hir_map = time(sess.time_passes(), + "indexing hir", + move || hir_map::map_crate(hir_forest, defs)); + write_out_deps(sess, &outputs, &id); @@ -746,15 +755,6 @@ pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate { krate } -pub fn make_map<'ast>(sess: &Session, - forest: &'ast mut hir_map::Forest) - -> hir_map::Map<'ast> { - // Construct the HIR map - time(sess.time_passes(), - "indexing hir", - move || hir_map::map_crate(forest)) -} - /// Run the resolution, typechecking, region checking and other /// miscellaneous analysis passes on the crate. Return various /// structures carrying the results of the analysis. diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index cde5ba19859..228cb8d75af 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -738,7 +738,8 @@ pub fn pretty_print_input(sess: Session, let _ignore = dep_graph.in_ignore(); let ast_map = if compute_ast_map { hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); - let map = driver::make_map(&sess, &mut hir_forest); + let defs = hir_map::collect_defs(hir_forest); + let map = hir_map::map_crate(hir_forest, defs); Some(map) } else { None From 84c3f898f93e294f2e50ceef271bd781b1ff6b9a Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 14:51:21 +1200 Subject: [PATCH 11/15] def_collector and crate reader operate on AST instead of HIR And move extern crate reading earlier in the driver --- src/librustc/hir/map/def_collector.rs | 92 +++++++++++++-------------- src/librustc/hir/map/mod.rs | 28 ++++---- src/librustc_driver/driver.rs | 52 +++++++-------- src/librustc_driver/pretty.rs | 10 +-- src/librustc_metadata/creader.rs | 80 ++++++++--------------- 5 files changed, 112 insertions(+), 150 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 974791f62bb..a259c5a0f31 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -10,10 +10,10 @@ use super::*; -use hir::*; -use hir::intravisit::Visitor; use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; -use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; + +use syntax::ast::*; +use syntax::visit; /// Creates def ids for nodes in the HIR. pub struct DefCollector<'ast> { @@ -80,31 +80,23 @@ impl<'ast> DefCollector<'ast> { } } -impl<'ast> Visitor<'ast> for DefCollector<'ast> { - /// Because we want to track parent items and so forth, enable - /// deep walking so that we walk nested items in the context of - /// their outer items. - fn visit_nested_item(&mut self, item: ItemId) { - debug!("visit_nested_item: {:?}", item); - self.visit_item(self.krate.item(item.id)) - } - +impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { fn visit_item(&mut self, i: &'ast Item) { debug!("visit_item: {:?}", i); // Pick the def data. This need not be unique, but the more // information we encapsulate into let def_data = match i.node { - ItemDefaultImpl(..) | ItemImpl(..) => + ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => DefPathData::Impl, - ItemEnum(..) | ItemStruct(..) | ItemTrait(..) | - ItemExternCrate(..) | ItemMod(..) | ItemForeignMod(..) | - ItemTy(..) => - DefPathData::TypeNs(i.name), - ItemStatic(..) | ItemConst(..) | ItemFn(..) => - DefPathData::ValueNs(i.name), - ItemUse(..) => - DefPathData::Misc, + ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Trait(..) | + ItemKind::ExternCrate(..) | ItemKind::Mod(..) | ItemKind::ForeignMod(..) | + ItemKind::Ty(..) => + DefPathData::TypeNs(i.ident.name), + ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => + DefPathData::ValueNs(i.ident.name), + ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name), + ItemKind::Use(..) => DefPathData::Misc, }; let def = self.create_def(i.id, def_data); @@ -113,21 +105,22 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { self.parent_def = Some(def); match i.node { - ItemEnum(ref enum_definition, _) => { + ItemKind::Enum(ref enum_definition, _) => { for v in &enum_definition.variants { let variant_def_index = self.create_def(v.node.data.id(), - DefPathData::EnumVariant(v.node.name)); + DefPathData::EnumVariant(v.node.name.name)); for field in v.node.data.fields() { - self.create_def_with_parent( - Some(variant_def_index), - field.id, - DefPathData::Field(field.name)); + if let Some(ident) = field.ident { + self.create_def_with_parent(Some(variant_def_index), + field.id, + DefPathData::Field(ident.name)); + } } } } - ItemStruct(ref struct_def, _) => { + ItemKind::Struct(ref struct_def, _) => { // If this is a tuple-like struct, register the constructor. if !struct_def.is_struct() { self.create_def(struct_def.id(), @@ -135,37 +128,40 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { } for field in struct_def.fields() { - self.create_def(field.id, DefPathData::Field(field.name)); + if let Some(ident) = field.ident { + self.create_def(field.id, DefPathData::Field(ident.name)); + } } } _ => {} } - intravisit::walk_item(self, i); + visit::walk_item(self, i); self.parent_def = parent_def; } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); + let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name)); let parent_def = self.parent_def; self.parent_def = Some(def); - intravisit::walk_foreign_item(self, foreign_item); + visit::walk_foreign_item(self, foreign_item); self.parent_def = parent_def; } fn visit_generics(&mut self, generics: &'ast Generics) { for ty_param in generics.ty_params.iter() { self.create_def(ty_param.id, - DefPathData::TypeParam(ty_param.name)); + DefPathData::TypeParam(ty_param.ident.name)); } - intravisit::walk_generics(self, generics); + visit::walk_generics(self, generics); } fn visit_trait_item(&mut self, ti: &'ast TraitItem) { let def_data = match ti.node { - MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::ValueNs(ti.name), - TypeTraitItem(..) => DefPathData::TypeNs(ti.name), + TraitItemKind::Method(..) | TraitItemKind::Const(..) => + DefPathData::ValueNs(ti.ident.name), + TraitItemKind::Type(..) => DefPathData::TypeNs(ti.ident.name), }; let def = self.create_def(ti.id, def_data); @@ -174,21 +170,23 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { self.parent_def = Some(def); match ti.node { - ConstTraitItem(_, Some(ref expr)) => { + TraitItemKind::Const(_, Some(ref expr)) => { self.create_def(expr.id, DefPathData::Initializer); } _ => { } } - intravisit::walk_trait_item(self, ti); + visit::walk_trait_item(self, ti); self.parent_def = parent_def; } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { let def_data = match ii.node { - ImplItemKind::Method(..) | ImplItemKind::Const(..) => DefPathData::ValueNs(ii.name), - ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), + ImplItemKind::Method(..) | ImplItemKind::Const(..) => + DefPathData::ValueNs(ii.ident.name), + ImplItemKind::Type(..) => DefPathData::TypeNs(ii.ident.name), + ImplItemKind::Macro(..) => DefPathData::MacroDef(ii.ident.name), }; let def = self.create_def(ii.id, def_data); @@ -203,7 +201,7 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { _ => { } } - intravisit::walk_impl_item(self, ii); + visit::walk_impl_item(self, ii); self.parent_def = parent_def; } @@ -220,28 +218,28 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { self.parent_def = Some(def); } - intravisit::walk_pat(self, pat); + visit::walk_pat(self, pat); self.parent_def = parent_def; } fn visit_expr(&mut self, expr: &'ast Expr) { let parent_def = self.parent_def; - if let ExprClosure(..) = expr.node { + if let ExprKind::Closure(..) = expr.node { let def = self.create_def(expr.id, DefPathData::ClosureExpr); self.parent_def = Some(def); } - intravisit::walk_expr(self, expr); + visit::walk_expr(self, expr); self.parent_def = parent_def; } fn visit_stmt(&mut self, stmt: &'ast Stmt) { - intravisit::walk_stmt(self, stmt); + visit::walk_stmt(self, stmt); } fn visit_block(&mut self, block: &'ast Block) { - intravisit::walk_block(self, block); + visit::walk_block(self, block); } fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { @@ -249,6 +247,6 @@ impl<'ast> Visitor<'ast> for DefCollector<'ast> { } fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { - self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name)); } } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 70071c224f8..b1954255278 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -22,9 +22,10 @@ use middle::cstore::InlinedItem as II; use hir::def_id::{CRATE_DEF_INDEX, DefId}; use syntax::abi::Abi; -use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID}; +use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, }; use syntax::attr::ThinAttributesExt; use syntax::codemap::{Span, Spanned}; +use syntax::visit; use hir::*; use hir::fold::Folder; @@ -782,10 +783,10 @@ impl Folder for IdAndSpanUpdater { } } -pub fn collect_definitions<'ast>(forest: &'ast mut Forest) -> Definitions { - let mut def_collector = DefCollector::root(&forest.krate); - intravisit::walk_crate(&mut def_collector, &forest.krate); - def_collector.definitions +pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions { + let mut def_collector = DefCollector::root(krate); + visit::walk_crate(&mut def_collector, krate); + def_collector.definitions } pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Map<'ast> { @@ -842,14 +843,15 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii = map.forest.inlined_items.alloc(ii); let ii_parent_id = fld.new_id(DUMMY_NODE_ID); - let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); - let mut def_collector = DefCollector::extend(map.krate(), - ii_parent_id, - parent_def_path.clone(), - parent_def_id, - defs); - ii.visit(&mut def_collector); - *map.definitions.borrow_mut() = def_collector.definitions; + // TODO need to save defs in metadata :-( + // let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); + // let mut def_collector = DefCollector::extend(map.krate(), + // ii_parent_id, + // parent_def_path.clone(), + // parent_def_id, + // defs); + // ii.visit(&mut def_collector); + // *map.definitions.borrow_mut() = def_collector.definitions; let mut collector = NodeCollector::extend(map.krate(), ii, diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index d63cf875632..6724c0ed8eb 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -122,32 +122,22 @@ pub fn compile_input(sess: &Session, let expanded_crate = assign_node_ids(sess, expanded_crate); let dep_graph = DepGraph::new(sess.opts.build_dep_graph); - // TODO - // time(sess.time_passes(), - // "external crate/lib resolution", - // || LocalCrateReader::new(sess, &cstore, &defs, &id).read_crates()); + // Collect defintions for def ids. + let defs = time(sess.time_passes(), + "collecting defs", + || hir_map::collect_definitions(&expanded_crate)); - // TODO - panic!(); - - // TODO CrateMap result - // let resolve::CrateMap { - // def_map, - // freevars, - // export_map, - // trait_map, - // glob_map, - // } = time(sess.time_passes(), - // "name resolution", - // || resolve::resolve_crate(sess, &hir_map, control.make_glob_map)); + time(sess.time_passes(), + "external crate/lib resolution", + || LocalCrateReader::new(sess, &cstore, &defs, &expanded_crate, &id) + .read_crates(&dep_graph)); // Lower ast -> hir. let lcx = LoweringContext::new(sess, Some(&expanded_crate)); - let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); - let mut hir_forest = time(sess.time_passes(), - "lowering ast -> hir", - || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate), - dep_graph)); + let hir_forest = &mut time(sess.time_passes(), + "lowering ast -> hir", + || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate), + dep_graph)); // Discard MTWT tables that aren't required past lowering to HIR. if !sess.opts.debugging_opts.keep_mtwt_tables && @@ -156,10 +146,6 @@ pub fn compile_input(sess: &Session, } let arenas = ty::CtxtArenas::new(); - // Collect defintions for def ids. - let defs = time(sess.time_passes(), - "collecting defs", - move || hir_map::collect_defs(hir_forest)); // Construct the HIR map let hir_map = time(sess.time_passes(), @@ -201,10 +187,10 @@ pub fn compile_input(sess: &Session, }; phase_3_run_analysis_passes(sess, - &cstore, hir_map, &arenas, &id, + control.make_glob_map, |tcx, mir_map, analysis, result| { { // Eventually, we will want to track plugins. @@ -759,10 +745,10 @@ pub fn assign_node_ids(sess: &Session, krate: ast::Crate) -> ast::Crate { /// miscellaneous analysis passes on the crate. Return various /// structures carrying the results of the analysis. pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, - cstore: &CStore, hir_map: hir_map::Map<'tcx>, arenas: &'tcx ty::CtxtArenas<'tcx>, name: &str, + make_glob_map: resolve::MakeGlobMap, f: F) -> Result where F: FnOnce(&TyCtxt<'tcx>, Option>, ty::CrateAnalysis, CompileResult) -> R @@ -787,6 +773,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, }) })?; + let resolve::CrateMap { + def_map, + freevars, + export_map, + trait_map, + glob_map, + } = time(sess.time_passes(), + "name resolution", + || resolve::resolve_crate(sess, &hir_map, make_glob_map)); + let mut analysis = ty::CrateAnalysis { export_map: export_map, access_levels: AccessLevels::default(), diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 228cb8d75af..2e3a477e048 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -179,7 +179,6 @@ impl PpSourceMode { } fn call_with_pp_support_hir<'tcx, A, B, F>(&self, sess: &'tcx Session, - cstore: &CStore, ast_map: &hir_map::Map<'tcx>, arenas: &'tcx ty::CtxtArenas<'tcx>, id: &str, @@ -206,7 +205,6 @@ impl PpSourceMode { } PpmTyped => { abort_on_err(driver::phase_3_run_analysis_passes(sess, - cstore, ast_map.clone(), arenas, id, @@ -737,9 +735,9 @@ pub fn pretty_print_input(sess: Session, let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); let ast_map = if compute_ast_map { + let defs = hir_map::collect_definitions(&krate); hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); - let defs = hir_map::collect_defs(hir_forest); - let map = hir_map::map_crate(hir_forest, defs); + let map = hir_map::map_crate(&mut hir_forest, defs); Some(map) } else { None @@ -778,7 +776,6 @@ pub fn pretty_print_input(sess: Session, (PpmHir(s), None) => { let out: &mut Write = &mut out; s.call_with_pp_support_hir(&sess, - cstore, &ast_map.unwrap(), &arenas, &id, @@ -800,7 +797,6 @@ pub fn pretty_print_input(sess: Session, (PpmHir(s), Some(uii)) => { let out: &mut Write = &mut out; s.call_with_pp_support_hir(&sess, - cstore, &ast_map.unwrap(), &arenas, &id, @@ -841,7 +837,6 @@ pub fn pretty_print_input(sess: Session, None }; abort_on_err(driver::phase_3_run_analysis_passes(&sess, - &cstore, ast_map, &arenas, &id, @@ -888,7 +883,6 @@ pub fn pretty_print_input(sess: Session, Some(code) => { let variants = gather_flowgraph_variants(&sess); abort_on_err(driver::phase_3_run_analysis_passes(&sess, - &cstore, ast_map, &arenas, &id, diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 8ec238f4b24..4ba59a3d7eb 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -18,7 +18,7 @@ use decoder; use loader::{self, CratePaths}; use rustc::hir::svh::Svh; -use rustc::dep_graph::DepNode; +use rustc::dep_graph::{DepGraph, DepNode}; use rustc::session::{config, Session}; use rustc::session::search_paths::PathKind; use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate}; @@ -37,15 +37,15 @@ use syntax::parse; use syntax::attr; use syntax::attr::AttrMetaMethods; use syntax::parse::token::InternedString; -use rustc::hir::intravisit::Visitor; -use rustc::hir; +use syntax::visit; use log; -pub struct LocalCrateReader<'a, 'b:'a> { +pub struct LocalCrateReader<'a> { sess: &'a Session, cstore: &'a CStore, creader: CrateReader<'a>, - ast_map: &'a hir_map::Map<'b>, + krate: &'a ast::Crate, + defintions: &'a hir_map::Definitions, } pub struct CrateReader<'a> { @@ -56,8 +56,8 @@ pub struct CrateReader<'a> { local_crate_name: String, } -impl<'a, 'b, 'hir> Visitor<'hir> for LocalCrateReader<'a, 'b> { - fn visit_item(&mut self, a: &'hir hir::Item) { +impl<'a, 'ast> visit::Visitor<'ast> for LocalCrateReader<'a> { + fn visit_item(&mut self, a: &'ast ast::Item) { self.process_item(a); } } @@ -80,10 +80,6 @@ fn dump_crates(cstore: &CStore) { fn should_link(i: &ast::Item) -> bool { !attr::contains_name(&i.attrs, "no_link") } -// Dup for the hir -fn should_link_hir(i: &hir::Item) -> bool { - !attr::contains_name(&i.attrs, "no_link") -} struct CrateInfo { ident: String, @@ -181,31 +177,6 @@ impl<'a> CrateReader<'a> { } } - // Dup of the above, but for the hir - fn extract_crate_info_hir(&self, i: &hir::Item) -> Option { - match i.node { - hir::ItemExternCrate(ref path_opt) => { - debug!("resolving extern crate stmt. ident: {} path_opt: {:?}", - i.name, path_opt); - let name = match *path_opt { - Some(name) => { - validate_crate_name(Some(self.sess), &name.as_str(), - Some(i.span)); - name.to_string() - } - None => i.name.to_string(), - }; - Some(CrateInfo { - ident: i.name.to_string(), - name: name, - id: i.id, - should_link: should_link_hir(i), - }) - } - _ => None - } - } - fn existing_match(&self, name: &str, hash: Option<&Svh>, kind: PathKind) -> Option { let mut ret = None; @@ -776,29 +747,30 @@ impl<'a> CrateReader<'a> { } } -impl<'a, 'b> LocalCrateReader<'a, 'b> { +impl<'a> LocalCrateReader<'a> { pub fn new(sess: &'a Session, cstore: &'a CStore, - map: &'a hir_map::Map<'b>, + defs: &'a hir_map::Definitions, + krate: &'a ast::Crate, local_crate_name: &str) - -> LocalCrateReader<'a, 'b> { + -> LocalCrateReader<'a> { LocalCrateReader { sess: sess, cstore: cstore, creader: CrateReader::new(sess, cstore, local_crate_name), - ast_map: map, + krate: krate, + defintions: defs, } } // Traverses an AST, reading all the information about use'd crates and // extern libraries necessary for later resolving, typechecking, linking, // etc. - pub fn read_crates(&mut self) { - let _task = self.ast_map.dep_graph.in_task(DepNode::CrateReader); - let krate = self.ast_map.krate(); + pub fn read_crates(&mut self, dep_graph: &DepGraph) { + let _task = dep_graph.in_task(DepNode::CrateReader); - self.process_crate(krate); - krate.visit_all_items(self); + self.process_crate(self.krate); + visit::walk_crate(self, self.krate); self.creader.inject_allocator_crate(); if log_enabled!(log::INFO) { @@ -811,7 +783,7 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { self.creader.register_statically_included_foreign_items(); } - fn process_crate(&self, c: &hir::Crate) { + fn process_crate(&self, c: &ast::Crate) { for a in c.attrs.iter().filter(|m| m.name() == "link_args") { if let Some(ref linkarg) = a.value_str() { self.cstore.add_used_link_args(&linkarg); @@ -819,14 +791,14 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { } } - fn process_item(&mut self, i: &hir::Item) { + fn process_item(&mut self, i: &ast::Item) { match i.node { - hir::ItemExternCrate(_) => { - if !should_link_hir(i) { + ast::ItemKind::ExternCrate(_) => { + if !should_link(i) { return; } - match self.creader.extract_crate_info_hir(i) { + match self.creader.extract_crate_info(i) { Some(info) => { let (cnum, _, _) = self.creader.resolve_crate(&None, &info.ident, @@ -835,9 +807,9 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { i.span, PathKind::Crate, true); - let def_id = self.ast_map.local_def_id(i.id); + let def_id = self.defintions.opt_local_def_id(i.id).unwrap(); - let len = self.ast_map.def_path(def_id).data.len(); + let len = self.defintions.def_path(def_id.index).data.len(); self.creader.update_extern_crate(cnum, ExternCrate { @@ -851,12 +823,12 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> { None => () } } - hir::ItemForeignMod(ref fm) => self.process_foreign_mod(i, fm), + ast::ItemKind::ForeignMod(ref fm) => self.process_foreign_mod(i, fm), _ => { } } } - fn process_foreign_mod(&mut self, i: &hir::Item, fm: &hir::ForeignMod) { + fn process_foreign_mod(&mut self, i: &ast::Item, fm: &ast::ForeignMod) { if fm.abi == Abi::Rust || fm.abi == Abi::RustIntrinsic || fm.abi == Abi::PlatformIntrinsic { return; } From 0c37d4bb1d1b8df21e1e4c8a634127cee871f7ab Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 17:24:30 +1200 Subject: [PATCH 12/15] refactoring --- src/librustc/hir/map/collector.rs | 119 +++++++++++------------ src/librustc/hir/map/def_collector.rs | 130 +++++++++++--------------- src/librustc/hir/map/mod.rs | 5 +- 3 files changed, 112 insertions(+), 142 deletions(-) diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index d7fccf03aec..c9d93319c03 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -70,6 +70,13 @@ impl<'ast> NodeCollector<'ast> { let entry = MapEntry::from_node(self.parent_node, node); self.insert_entry(id, entry); } + + fn with_parent(&mut self, parent_id: NodeId, f: F) { + let parent_node = self.parent_node; + self.parent_node = parent_id; + f(self); + self.parent_node = parent_node; + } } impl<'ast> Visitor<'ast> for NodeCollector<'ast> { @@ -86,51 +93,48 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { self.insert(i.id, NodeItem(i)); - let parent_node = self.parent_node; - self.parent_node = i.id; - - match i.node { - ItemEnum(ref enum_definition, _) => { - for v in &enum_definition.variants { - self.insert(v.node.data.id(), NodeVariant(v)); - } - } - ItemStruct(ref struct_def, _) => { - // If this is a tuple-like struct, register the constructor. - if !struct_def.is_struct() { - self.insert(struct_def.id(), NodeStructCtor(struct_def)); - } - } - ItemTrait(_, _, ref bounds, _) => { - for b in bounds.iter() { - if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { - self.insert(t.trait_ref.ref_id, NodeItem(i)); + self.with_parent(i.id, |this| { + match i.node { + ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + this.insert(v.node.data.id(), NodeVariant(v)); } } - } - ItemUse(ref view_path) => { - match view_path.node { - ViewPathList(_, ref paths) => { - for path in paths { - self.insert(path.node.id(), NodeItem(i)); + ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + this.insert(struct_def.id(), NodeStructCtor(struct_def)); + } + } + ItemTrait(_, _, ref bounds, _) => { + for b in bounds.iter() { + if let TraitTyParamBound(ref t, TraitBoundModifier::None) = *b { + this.insert(t.trait_ref.ref_id, NodeItem(i)); } } - _ => () } + ItemUse(ref view_path) => { + match view_path.node { + ViewPathList(_, ref paths) => { + for path in paths { + this.insert(path.node.id(), NodeItem(i)); + } + } + _ => () + } + } + _ => {} } - _ => {} - } - intravisit::walk_item(self, i); - self.parent_node = parent_node; + intravisit::walk_item(this, i); + }); } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { self.insert(foreign_item.id, NodeForeignItem(foreign_item)); - let parent_node = self.parent_node; - self.parent_node = foreign_item.id; - intravisit::walk_foreign_item(self, foreign_item); - self.parent_node = parent_node; + self.with_parent(foreign_item.id, |this| { + intravisit::walk_foreign_item(this, foreign_item); + }); } fn visit_generics(&mut self, generics: &'ast Generics) { @@ -144,50 +148,42 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_trait_item(&mut self, ti: &'ast TraitItem) { self.insert(ti.id, NodeTraitItem(ti)); - let parent_node = self.parent_node; - self.parent_node = ti.id; - - intravisit::walk_trait_item(self, ti); - - self.parent_node = parent_node; + self.with_parent(ti.id, |this| { + intravisit::walk_trait_item(this, ti); + }); } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { self.insert(ii.id, NodeImplItem(ii)); - let parent_node = self.parent_node; - self.parent_node = ii.id; - - intravisit::walk_impl_item(self, ii); - - self.parent_node = parent_node; + self.with_parent(ii.id, |this| { + intravisit::walk_impl_item(this, ii); + }); } fn visit_pat(&mut self, pat: &'ast Pat) { self.insert(pat.id, NodeLocal(pat)); - let parent_node = self.parent_node; - self.parent_node = pat.id; - intravisit::walk_pat(self, pat); - self.parent_node = parent_node; + self.with_parent(pat.id, |this| { + intravisit::walk_pat(this, pat); + }); } fn visit_expr(&mut self, expr: &'ast Expr) { self.insert(expr.id, NodeExpr(expr)); - let parent_node = self.parent_node; - self.parent_node = expr.id; - intravisit::walk_expr(self, expr); - self.parent_node = parent_node; + self.with_parent(expr.id, |this| { + intravisit::walk_expr(this, expr); + }); } fn visit_stmt(&mut self, stmt: &'ast Stmt) { let id = stmt.node.id(); self.insert(id, NodeStmt(stmt)); - let parent_node = self.parent_node; - self.parent_node = id; - intravisit::walk_stmt(self, stmt); - self.parent_node = parent_node; + + self.with_parent(id, |this| { + intravisit::walk_stmt(this, stmt); + }); } fn visit_fn(&mut self, fk: intravisit::FnKind<'ast>, fd: &'ast FnDecl, @@ -198,10 +194,9 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { fn visit_block(&mut self, block: &'ast Block) { self.insert(block.id, NodeBlock(block)); - let parent_node = self.parent_node; - self.parent_node = block.id; - intravisit::walk_block(self, block); - self.parent_node = parent_node; + self.with_parent(block.id, |this| { + intravisit::walk_block(this, block); + }); } fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) { diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index a259c5a0f31..9d6027932f6 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -16,16 +16,14 @@ use syntax::ast::*; use syntax::visit; /// Creates def ids for nodes in the HIR. -pub struct DefCollector<'ast> { - pub krate: &'ast Crate, +pub struct DefCollector { pub definitions: Definitions, pub parent_def: Option, } -impl<'ast> DefCollector<'ast> { - pub fn root(krate: &'ast Crate) -> DefCollector<'ast> { +impl DefCollector { + pub fn root() -> DefCollector { let mut collector = DefCollector { - krate: krate, definitions: Definitions::new(), parent_def: None, }; @@ -37,14 +35,12 @@ impl<'ast> DefCollector<'ast> { collector } - pub fn extend(krate: &'ast Crate, - parent_node: NodeId, + pub fn extend(parent_node: NodeId, parent_def_path: DefPath, parent_def_id: DefId, definitions: Definitions) - -> DefCollector<'ast> { + -> DefCollector { let mut collector = DefCollector { - krate: krate, parent_def: None, definitions: definitions, }; @@ -78,9 +74,16 @@ impl<'ast> DefCollector<'ast> { -> DefIndex { self.definitions.create_def_with_parent(parent, node_id, data) } + + fn with_parent(&mut self, parent_def: DefIndex, f: F) { + let parent = self.parent_def; + self.parent_def = Some(parent_def); + f(self); + self.parent_def = parent; + } } -impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { +impl<'ast> visit::Visitor<'ast> for DefCollector { fn visit_item(&mut self, i: &'ast Item) { debug!("visit_item: {:?}", i); @@ -98,60 +101,55 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name), ItemKind::Use(..) => DefPathData::Misc, }; - let def = self.create_def(i.id, def_data); - let parent_def = self.parent_def; - self.parent_def = Some(def); + self.with_parent(def, |this| { + match i.node { + ItemKind::Enum(ref enum_definition, _) => { + for v in &enum_definition.variants { + let variant_def_index = + this.create_def(v.node.data.id(), + DefPathData::EnumVariant(v.node.name.name)); - match i.node { - ItemKind::Enum(ref enum_definition, _) => { - for v in &enum_definition.variants { - let variant_def_index = - self.create_def(v.node.data.id(), - DefPathData::EnumVariant(v.node.name.name)); - - for field in v.node.data.fields() { - if let Some(ident) = field.ident { - self.create_def_with_parent(Some(variant_def_index), - field.id, - DefPathData::Field(ident.name)); + for field in v.node.data.fields() { + if let Some(ident) = field.ident { + this.create_def_with_parent(Some(variant_def_index), + field.id, + DefPathData::Field(ident.name)); + } } } } - } - ItemKind::Struct(ref struct_def, _) => { - // If this is a tuple-like struct, register the constructor. - if !struct_def.is_struct() { - self.create_def(struct_def.id(), - DefPathData::StructCtor); - } + ItemKind::Struct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + this.create_def(struct_def.id(), + DefPathData::StructCtor); + } - for field in struct_def.fields() { - if let Some(ident) = field.ident { - self.create_def(field.id, DefPathData::Field(ident.name)); + for field in struct_def.fields() { + if let Some(ident) = field.ident { + this.create_def(field.id, DefPathData::Field(ident.name)); + } } } + _ => {} } - _ => {} - } - visit::walk_item(self, i); - self.parent_def = parent_def; + visit::walk_item(this, i); + }); } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.ident.name)); - let parent_def = self.parent_def; - self.parent_def = Some(def); - visit::walk_foreign_item(self, foreign_item); - self.parent_def = parent_def; + self.with_parent(def, |this| { + visit::walk_foreign_item(this, foreign_item); + }); } fn visit_generics(&mut self, generics: &'ast Generics) { for ty_param in generics.ty_params.iter() { - self.create_def(ty_param.id, - DefPathData::TypeParam(ty_param.ident.name)); + self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.ident.name)); } visit::walk_generics(self, generics); @@ -165,20 +163,13 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { }; let def = self.create_def(ti.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match ti.node { - TraitItemKind::Const(_, Some(ref expr)) => { - self.create_def(expr.id, DefPathData::Initializer); + self.with_parent(def, |this| { + if let TraitItemKind::Const(_, Some(ref expr)) = ti.node { + this.create_def(expr.id, DefPathData::Initializer); } - _ => { } - } - visit::walk_trait_item(self, ti); - - self.parent_def = parent_def; + visit::walk_trait_item(this, ti); + }); } fn visit_impl_item(&mut self, ii: &'ast ImplItem) { @@ -190,20 +181,13 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { }; let def = self.create_def(ii.id, def_data); - - let parent_def = self.parent_def; - self.parent_def = Some(def); - - match ii.node { - ImplItemKind::Const(_, ref expr) => { - self.create_def(expr.id, DefPathData::Initializer); + self.with_parent(def, |this| { + if let ImplItemKind::Const(_, ref expr) = ii.node { + this.create_def(expr.id, DefPathData::Initializer); } - _ => { } - } - visit::walk_impl_item(self, ii); - - self.parent_def = parent_def; + visit::walk_impl_item(this, ii); + }); } fn visit_pat(&mut self, pat: &'ast Pat) { @@ -234,14 +218,6 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { self.parent_def = parent_def; } - fn visit_stmt(&mut self, stmt: &'ast Stmt) { - visit::walk_stmt(self, stmt); - } - - fn visit_block(&mut self, block: &'ast Block) { - visit::walk_block(self, block); - } - fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b1954255278..a505ad19889 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -784,7 +784,7 @@ impl Folder for IdAndSpanUpdater { } pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions { - let mut def_collector = DefCollector::root(krate); + let mut def_collector = DefCollector::root(); visit::walk_crate(&mut def_collector, krate); def_collector.definitions } @@ -845,8 +845,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, // TODO need to save defs in metadata :-( // let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); - // let mut def_collector = DefCollector::extend(map.krate(), - // ii_parent_id, + // let mut def_collector = DefCollector::extend(ii_parent_id, // parent_def_path.clone(), // parent_def_id, // defs); From 744be0b5aac8c06c60dabac3a7802a8117c946b2 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 14 Apr 2016 18:04:55 +1200 Subject: [PATCH 13/15] HIR visitor for DefCollector So that we can work with inlined HIR from metadata. --- src/librustc/hir/map/def_collector.rs | 174 +++++++++++++++++++++++++- src/librustc/hir/map/mod.rs | 15 ++- 2 files changed, 175 insertions(+), 14 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 9d6027932f6..f8d0243548f 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -10,20 +10,28 @@ use super::*; +use hir; +use hir::intravisit; use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex}; +use middle::cstore::InlinedItem; + use syntax::ast::*; use syntax::visit; /// Creates def ids for nodes in the HIR. -pub struct DefCollector { +pub struct DefCollector<'ast> { + // If we are walking HIR (c.f., AST), we need to keep a reference to the + // crate. + hir_crate: Option<&'ast hir::Crate>, pub definitions: Definitions, - pub parent_def: Option, + parent_def: Option, } -impl DefCollector { - pub fn root() -> DefCollector { +impl<'ast> DefCollector<'ast> { + pub fn root() -> DefCollector<'ast> { let mut collector = DefCollector { + hir_crate: None, definitions: Definitions::new(), parent_def: None, }; @@ -39,8 +47,9 @@ impl DefCollector { parent_def_path: DefPath, parent_def_id: DefId, definitions: Definitions) - -> DefCollector { + -> DefCollector<'ast> { let mut collector = DefCollector { + hir_crate: None, parent_def: None, definitions: definitions, }; @@ -57,6 +66,11 @@ impl DefCollector { collector } + pub fn walk_item(&mut self, ii: &'ast InlinedItem, krate: &'ast hir::Crate) { + self.hir_crate = Some(krate); + ii.visit(self); + } + fn parent_def(&self) -> Option { self.parent_def } @@ -83,7 +97,7 @@ impl DefCollector { } } -impl<'ast> visit::Visitor<'ast> for DefCollector { +impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { fn visit_item(&mut self, i: &'ast Item) { debug!("visit_item: {:?}", i); @@ -226,3 +240,151 @@ impl<'ast> visit::Visitor<'ast> for DefCollector { self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.ident.name)); } } + +// We walk the HIR rather than the AST when reading items from metadata. +impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> { + /// Because we want to track parent items and so forth, enable + /// deep walking so that we walk nested items in the context of + /// their outer items. + fn visit_nested_item(&mut self, item_id: hir::ItemId) { + debug!("visit_nested_item: {:?}", item_id); + let item = self.hir_crate.unwrap().item(item_id.id); + self.visit_item(item) + } + + fn visit_item(&mut self, i: &'ast hir::Item) { + debug!("visit_item: {:?}", i); + + // Pick the def data. This need not be unique, but the more + // information we encapsulate into + let def_data = match i.node { + hir::ItemDefaultImpl(..) | hir::ItemImpl(..) => + DefPathData::Impl, + hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemTrait(..) | + hir::ItemExternCrate(..) | hir::ItemMod(..) | hir::ItemForeignMod(..) | + hir::ItemTy(..) => + DefPathData::TypeNs(i.name), + hir::ItemStatic(..) | hir::ItemConst(..) | hir::ItemFn(..) => + DefPathData::ValueNs(i.name), + hir::ItemUse(..) => DefPathData::Misc, + }; + let def = self.create_def(i.id, def_data); + + self.with_parent(def, |this| { + match i.node { + hir::ItemEnum(ref enum_definition, _) => { + for v in &enum_definition.variants { + let variant_def_index = + this.create_def(v.node.data.id(), + DefPathData::EnumVariant(v.node.name)); + + for field in v.node.data.fields() { + this.create_def_with_parent(Some(variant_def_index), + field.id, + DefPathData::Field(field.name)); + } + } + } + hir::ItemStruct(ref struct_def, _) => { + // If this is a tuple-like struct, register the constructor. + if !struct_def.is_struct() { + this.create_def(struct_def.id(), + DefPathData::StructCtor); + } + + for field in struct_def.fields() { + this.create_def(field.id, DefPathData::Field(field.name)); + } + } + _ => {} + } + intravisit::walk_item(this, i); + }); + } + + fn visit_foreign_item(&mut self, foreign_item: &'ast hir::ForeignItem) { + let def = self.create_def(foreign_item.id, DefPathData::ValueNs(foreign_item.name)); + + self.with_parent(def, |this| { + intravisit::walk_foreign_item(this, foreign_item); + }); + } + + fn visit_generics(&mut self, generics: &'ast hir::Generics) { + for ty_param in generics.ty_params.iter() { + self.create_def(ty_param.id, DefPathData::TypeParam(ty_param.name)); + } + + intravisit::walk_generics(self, generics); + } + + fn visit_trait_item(&mut self, ti: &'ast hir::TraitItem) { + let def_data = match ti.node { + hir::MethodTraitItem(..) | hir::ConstTraitItem(..) => + DefPathData::ValueNs(ti.name), + hir::TypeTraitItem(..) => DefPathData::TypeNs(ti.name), + }; + + let def = self.create_def(ti.id, def_data); + self.with_parent(def, |this| { + if let hir::ConstTraitItem(_, Some(ref expr)) = ti.node { + this.create_def(expr.id, DefPathData::Initializer); + } + + intravisit::walk_trait_item(this, ti); + }); + } + + fn visit_impl_item(&mut self, ii: &'ast hir::ImplItem) { + let def_data = match ii.node { + hir::ImplItemKind::Method(..) | hir::ImplItemKind::Const(..) => + DefPathData::ValueNs(ii.name), + hir::ImplItemKind::Type(..) => DefPathData::TypeNs(ii.name), + }; + + let def = self.create_def(ii.id, def_data); + self.with_parent(def, |this| { + if let hir::ImplItemKind::Const(_, ref expr) = ii.node { + this.create_def(expr.id, DefPathData::Initializer); + } + + intravisit::walk_impl_item(this, ii); + }); + } + + fn visit_pat(&mut self, pat: &'ast hir::Pat) { + let maybe_binding = match pat.node { + hir::PatKind::Ident(_, id, _) => Some(id.node), + _ => None + }; + + let parent_def = self.parent_def; + if let Some(id) = maybe_binding { + let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + self.parent_def = Some(def); + } + + intravisit::walk_pat(self, pat); + self.parent_def = parent_def; + } + + fn visit_expr(&mut self, expr: &'ast hir::Expr) { + let parent_def = self.parent_def; + + if let hir::ExprClosure(..) = expr.node { + let def = self.create_def(expr.id, DefPathData::ClosureExpr); + self.parent_def = Some(def); + } + + intravisit::walk_expr(self, expr); + self.parent_def = parent_def; + } + + fn visit_lifetime_def(&mut self, def: &'ast hir::LifetimeDef) { + self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name)); + } + + fn visit_macro_def(&mut self, macro_def: &'ast hir::MacroDef) { + self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name)); + } +} \ No newline at end of file diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index a505ad19889..1d0c40646b5 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -843,14 +843,13 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii = map.forest.inlined_items.alloc(ii); let ii_parent_id = fld.new_id(DUMMY_NODE_ID); - // TODO need to save defs in metadata :-( - // let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); - // let mut def_collector = DefCollector::extend(ii_parent_id, - // parent_def_path.clone(), - // parent_def_id, - // defs); - // ii.visit(&mut def_collector); - // *map.definitions.borrow_mut() = def_collector.definitions; + let defs = mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()); + let mut def_collector = DefCollector::extend(ii_parent_id, + parent_def_path.clone(), + parent_def_id, + defs); + def_collector.walk_item(ii, map.krate()); + *map.definitions.borrow_mut() = def_collector.definitions; let mut collector = NodeCollector::extend(map.krate(), ii, From 1d5a29cf0e40c412bb2e090aadcf3ebfb1d5fa13 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 18 Apr 2016 10:30:55 +1200 Subject: [PATCH 14/15] debugging, misc fixes --- src/librustc/hir/lowering.rs | 218 ++++++++++++++------- src/librustc/hir/map/collector.rs | 7 +- src/librustc/hir/map/def_collector.rs | 46 ++--- src/librustc/hir/map/mod.rs | 8 +- src/librustc_driver/driver.rs | 9 +- src/librustc_driver/lib.rs | 11 +- src/librustc_driver/pretty.rs | 19 +- src/librustc_driver/test.rs | 12 +- src/librustc_metadata/astencode.rs | 8 +- src/librustc_metadata/creader.rs | 11 +- src/librustc_save_analysis/csv_dumper.rs | 4 +- src/librustc_save_analysis/dump_visitor.rs | 23 +-- src/librustc_save_analysis/lib.rs | 11 +- src/librustc_save_analysis/span_utils.rs | 2 + src/librustdoc/core.rs | 13 +- src/librustdoc/test.rs | 8 +- src/test/run-make/execution-engine/test.rs | 12 +- 17 files changed, 260 insertions(+), 162 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 7c476657041..0a01cc91f0e 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -62,6 +62,9 @@ // in the HIR, especially for multiple identifiers. use hir; +use hir::map::Definitions; +use hir::map::definitions::DefPathData; +use hir::def_id::DefIndex; use std::collections::BTreeMap; use std::collections::HashMap; @@ -92,10 +95,20 @@ pub struct LoweringContext<'a> { // A copy of cached_id, but is also set to an id while a node is lowered for // the first time. gensym_key: Cell, + // We must keep the set of definitions up to date as we add nodes that + // weren't in the AST. + definitions: Option<&'a RefCell>, + // As we walk the AST we must keep track of the current 'parent' def id (in + // the form of a DefIndex) so that if we create a new node which introduces + // a definition, then we can properly create the def id. + parent_def: Cell>, } impl<'a, 'hir> LoweringContext<'a> { - pub fn new(id_assigner: &'a NodeIdAssigner, c: Option<&Crate>) -> LoweringContext<'a> { + pub fn new(id_assigner: &'a NodeIdAssigner, + c: Option<&Crate>, + defs: &'a RefCell) + -> LoweringContext<'a> { let crate_root = c.and_then(|c| { if std_inject::no_core(c) { None @@ -113,6 +126,23 @@ impl<'a, 'hir> LoweringContext<'a> { cached_id: Cell::new(0), gensym_cache: RefCell::new(HashMap::new()), gensym_key: Cell::new(0), + definitions: Some(defs), + parent_def: Cell::new(None), + } + } + + // Only use this when you want a LoweringContext for testing and won't look + // up def ids for anything created during lowering. + pub fn testing_context(id_assigner: &'a NodeIdAssigner) -> LoweringContext<'a> { + LoweringContext { + crate_root: None, + id_cache: RefCell::new(HashMap::new()), + id_assigner: id_assigner, + cached_id: Cell::new(0), + gensym_cache: RefCell::new(HashMap::new()), + gensym_key: Cell::new(0), + definitions: None, + parent_def: Cell::new(None), } } @@ -146,6 +176,25 @@ impl<'a, 'hir> LoweringContext<'a> { fn diagnostic(&self) -> &Handler { self.id_assigner.diagnostic() } + + fn with_parent_def T>(&self, parent_id: NodeId, f: F) -> T { + if self.definitions.is_none() { + // This should only be used for testing. + return f(); + } + + let old_def = self.parent_def.get(); + self.parent_def.set(Some(self.get_def(parent_id))); + let result = f(); + self.parent_def.set(old_def); + + result + } + + fn get_def(&self, id: NodeId) -> DefIndex { + let defs = self.definitions.unwrap().borrow(); + defs.opt_def_index(id).unwrap() + } } // Utility fn for setting and unsetting the cached id. @@ -733,47 +782,51 @@ pub fn lower_item_kind(lctx: &LoweringContext, i: &ItemKind) -> hir::Item_ { } pub fn lower_trait_item(lctx: &LoweringContext, i: &TraitItem) -> hir::TraitItem { - hir::TraitItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - TraitItemKind::Const(ref ty, ref default) => { - hir::ConstTraitItem(lower_ty(lctx, ty), - default.as_ref().map(|x| lower_expr(lctx, x))) - } - TraitItemKind::Method(ref sig, ref body) => { - hir::MethodTraitItem(lower_method_sig(lctx, sig), - body.as_ref().map(|x| lower_block(lctx, x))) - } - TraitItemKind::Type(ref bounds, ref default) => { - hir::TypeTraitItem(lower_bounds(lctx, bounds), - default.as_ref().map(|x| lower_ty(lctx, x))) - } - }, - span: i.span, - } + lctx.with_parent_def(i.id, || { + hir::TraitItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + node: match i.node { + TraitItemKind::Const(ref ty, ref default) => { + hir::ConstTraitItem(lower_ty(lctx, ty), + default.as_ref().map(|x| lower_expr(lctx, x))) + } + TraitItemKind::Method(ref sig, ref body) => { + hir::MethodTraitItem(lower_method_sig(lctx, sig), + body.as_ref().map(|x| lower_block(lctx, x))) + } + TraitItemKind::Type(ref bounds, ref default) => { + hir::TypeTraitItem(lower_bounds(lctx, bounds), + default.as_ref().map(|x| lower_ty(lctx, x))) + } + }, + span: i.span, + } + }) } pub fn lower_impl_item(lctx: &LoweringContext, i: &ImplItem) -> hir::ImplItem { - hir::ImplItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - vis: lower_visibility(lctx, &i.vis), - defaultness: lower_defaultness(lctx, i.defaultness), - node: match i.node { - ImplItemKind::Const(ref ty, ref expr) => { - hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr)) - } - ImplItemKind::Method(ref sig, ref body) => { - hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body)) - } - ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)), - ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), - }, - span: i.span, - } + lctx.with_parent_def(i.id, || { + hir::ImplItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + vis: lower_visibility(lctx, &i.vis), + defaultness: lower_defaultness(lctx, i.defaultness), + node: match i.node { + ImplItemKind::Const(ref ty, ref expr) => { + hir::ImplItemKind::Const(lower_ty(lctx, ty), lower_expr(lctx, expr)) + } + ImplItemKind::Method(ref sig, ref body) => { + hir::ImplItemKind::Method(lower_method_sig(lctx, sig), lower_block(lctx, body)) + } + ImplItemKind::Type(ref ty) => hir::ImplItemKind::Type(lower_ty(lctx, ty)), + ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), + }, + span: i.span, + } + }) } pub fn lower_mod(lctx: &LoweringContext, m: &Mod) -> hir::Mod { @@ -831,7 +884,9 @@ pub fn lower_item_id(_lctx: &LoweringContext, i: &Item) -> hir::ItemId { } pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { - let node = lower_item_kind(lctx, &i.node); + let node = lctx.with_parent_def(i.id, || { + lower_item_kind(lctx, &i.node) + }); hir::Item { id: i.id, @@ -844,21 +899,23 @@ pub fn lower_item(lctx: &LoweringContext, i: &Item) -> hir::Item { } pub fn lower_foreign_item(lctx: &LoweringContext, i: &ForeignItem) -> hir::ForeignItem { - hir::ForeignItem { - id: i.id, - name: i.ident.name, - attrs: lower_attrs(lctx, &i.attrs), - node: match i.node { - ForeignItemKind::Fn(ref fdec, ref generics) => { - hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) - } - ForeignItemKind::Static(ref t, m) => { - hir::ForeignItemStatic(lower_ty(lctx, t), m) - } - }, - vis: lower_visibility(lctx, &i.vis), - span: i.span, - } + lctx.with_parent_def(i.id, || { + hir::ForeignItem { + id: i.id, + name: i.ident.name, + attrs: lower_attrs(lctx, &i.attrs), + node: match i.node { + ForeignItemKind::Fn(ref fdec, ref generics) => { + hir::ForeignItemFn(lower_fn_decl(lctx, fdec), lower_generics(lctx, generics)) + } + ForeignItemKind::Static(ref t, m) => { + hir::ForeignItemStatic(lower_ty(lctx, t), m) + } + }, + vis: lower_visibility(lctx, &i.vis), + span: i.span, + } + }) } pub fn lower_method_sig(lctx: &LoweringContext, sig: &MethodSig) -> hir::MethodSig { @@ -926,9 +983,11 @@ pub fn lower_pat(lctx: &LoweringContext, p: &Pat) -> P { node: match p.node { PatKind::Wild => hir::PatKind::Wild, PatKind::Ident(ref binding_mode, pth1, ref sub) => { - hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), - respan(pth1.span, lower_ident(lctx, pth1.node)), - sub.as_ref().map(|x| lower_pat(lctx, x))) + lctx.with_parent_def(p.id, || { + hir::PatKind::Ident(lower_binding_mode(lctx, binding_mode), + respan(pth1.span, lower_ident(lctx, pth1.node)), + sub.as_ref().map(|x| lower_pat(lctx, x))) + }) } PatKind::Lit(ref e) => hir::PatKind::Lit(lower_expr(lctx, e)), PatKind::TupleStruct(ref pth, ref pats) => { @@ -1202,9 +1261,11 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { hir::MatchSource::Normal) } ExprKind::Closure(capture_clause, ref decl, ref body) => { - hir::ExprClosure(lower_capture_clause(lctx, capture_clause), - lower_fn_decl(lctx, decl), - lower_block(lctx, body)) + lctx.with_parent_def(e.id, || { + hir::ExprClosure(lower_capture_clause(lctx, capture_clause), + lower_fn_decl(lctx, decl), + lower_block(lctx, body)) + }) } ExprKind::Block(ref blk) => hir::ExprBlock(lower_block(lctx, blk)), ExprKind::Assign(ref el, ref er) => { @@ -1602,7 +1663,12 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { // `{ let _result = ...; _result }` // underscore prevents an unused_variables lint if the head diverges let result_ident = lctx.str_to_ident("_result"); - let let_stmt = stmt_let(lctx, e.span, false, result_ident, match_expr, None); + let let_stmt = stmt_let(lctx, + e.span, + false, + result_ident, + match_expr, + None); let result = expr_ident(lctx, e.span, result_ident, None); let block = block_all(lctx, e.span, hir_vec![let_stmt], Some(result)); // add the attributes to the outer returned expr node @@ -1655,7 +1721,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { let err_ctor = expr_path(lctx, path, None); expr_call(lctx, e.span, err_ctor, hir_vec![from_expr], None) }; - let err_pat = pat_err(lctx, e.span, pat_ident(lctx, e.span, err_ident)); + let err_pat = pat_err(lctx, e.span, + pat_ident(lctx, e.span, err_ident)); let ret_expr = expr(lctx, e.span, hir::Expr_::ExprRet(Some(err_expr)), None); @@ -1938,12 +2005,22 @@ fn pat_ident_binding_mode(lctx: &LoweringContext, bm: hir::BindingMode) -> P { let pat_ident = hir::PatKind::Ident(bm, - Spanned { - span: span, - node: ident, - }, - None); - pat(lctx, span, pat_ident) + Spanned { + span: span, + node: ident, + }, + None); + + let pat = pat(lctx, span, pat_ident); + + if let Some(defs) = lctx.definitions { + let mut defs = defs.borrow_mut(); + defs.create_def_with_parent(lctx.parent_def.get(), + pat.id, + DefPathData::Binding(ident.name)); + } + + pat } fn pat_wild(lctx: &LoweringContext, span: Span) -> P { @@ -2130,7 +2207,8 @@ mod test { let ast_in = quote_expr!(&cx, in HEAP { foo() }); let ast_in = assigner.fold_expr(ast_in); - let lctx = LoweringContext::new(&assigner, None); + let lctx = LoweringContext::testing_context(&assigner); + let hir1 = lower_expr(&lctx, &ast_if_let); let hir2 = lower_expr(&lctx, &ast_if_let); assert!(hir1 == hir2); diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index c9d93319c03..9f55f46541c 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -162,7 +162,12 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> { } fn visit_pat(&mut self, pat: &'ast Pat) { - self.insert(pat.id, NodeLocal(pat)); + let node = if let PatKind::Ident(..) = pat.node { + NodeLocal(pat) + } else { + NodePat(pat) + }; + self.insert(pat.id, node); self.with_parent(pat.id, |this| { intravisit::walk_pat(this, pat); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index f8d0243548f..b2456f4ab87 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -18,6 +18,7 @@ use middle::cstore::InlinedItem; use syntax::ast::*; use syntax::visit; +use syntax::parse::token; /// Creates def ids for nodes in the HIR. pub struct DefCollector<'ast> { @@ -35,8 +36,9 @@ impl<'ast> DefCollector<'ast> { definitions: Definitions::new(), parent_def: None, }; - let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); - assert_eq!(result, CRATE_DEF_INDEX); + let root = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot); + assert_eq!(root, CRATE_DEF_INDEX); + collector.parent_def = Some(root); collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc); @@ -125,12 +127,12 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { this.create_def(v.node.data.id(), DefPathData::EnumVariant(v.node.name.name)); - for field in v.node.data.fields() { - if let Some(ident) = field.ident { - this.create_def_with_parent(Some(variant_def_index), - field.id, - DefPathData::Field(ident.name)); - } + for (index, field) in v.node.data.fields().iter().enumerate() { + let name = field.ident.map(|ident| ident.name) + .unwrap_or(token::intern(&index.to_string())); + this.create_def_with_parent(Some(variant_def_index), + field.id, + DefPathData::Field(name)); } } } @@ -141,10 +143,10 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { DefPathData::StructCtor); } - for field in struct_def.fields() { - if let Some(ident) = field.ident { - this.create_def(field.id, DefPathData::Field(ident.name)); - } + for (index, field) in struct_def.fields().iter().enumerate() { + let name = field.ident.map(|ident| ident.name) + .unwrap_or(token::intern(&index.to_string())); + this.create_def(field.id, DefPathData::Field(name)); } } _ => {} @@ -205,14 +207,10 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { } fn visit_pat(&mut self, pat: &'ast Pat) { - let maybe_binding = match pat.node { - PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - let parent_def = self.parent_def; - if let Some(id) = maybe_binding { - let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + + if let PatKind::Ident(_, id, _) = pat.node { + let def = self.create_def(pat.id, DefPathData::Binding(id.node.name)); self.parent_def = Some(def); } @@ -353,14 +351,10 @@ impl<'ast> intravisit::Visitor<'ast> for DefCollector<'ast> { } fn visit_pat(&mut self, pat: &'ast hir::Pat) { - let maybe_binding = match pat.node { - hir::PatKind::Ident(_, id, _) => Some(id.node), - _ => None - }; - let parent_def = self.parent_def; - if let Some(id) = maybe_binding { - let def = self.create_def(pat.id, DefPathData::Binding(id.name)); + + if let hir::PatKind::Ident(_, id, _) = pat.node { + let def = self.create_def(pat.id, DefPathData::Binding(id.node.name)); self.parent_def = Some(def); } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 1d0c40646b5..92f8c9249c8 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -196,7 +196,7 @@ pub struct Map<'ast> { /// plain old integers. map: RefCell>>, - definitions: RefCell, + definitions: &'ast RefCell, } impl<'ast> Map<'ast> { @@ -789,7 +789,9 @@ pub fn collect_definitions<'ast>(krate: &'ast ast::Crate) -> Definitions { def_collector.definitions } -pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Map<'ast> { +pub fn map_crate<'ast>(forest: &'ast mut Forest, + definitions: &'ast RefCell) + -> Map<'ast> { let mut collector = NodeCollector::root(&forest.krate); intravisit::walk_crate(&mut collector, &forest.krate); let map = collector.map; @@ -814,7 +816,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest, definitions: Definitions) -> Ma forest: forest, dep_graph: forest.dep_graph.clone(), map: RefCell::new(map), - definitions: RefCell::new(definitions), + definitions: definitions, } } diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 6724c0ed8eb..26422e3194a 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -43,6 +43,7 @@ use super::Compilation; use serialize::json; +use std::cell::RefCell; use std::collections::HashMap; use std::env; use std::ffi::{OsString, OsStr}; @@ -123,9 +124,9 @@ pub fn compile_input(sess: &Session, let dep_graph = DepGraph::new(sess.opts.build_dep_graph); // Collect defintions for def ids. - let defs = time(sess.time_passes(), - "collecting defs", - || hir_map::collect_definitions(&expanded_crate)); + let defs = &RefCell::new(time(sess.time_passes(), + "collecting defs", + || hir_map::collect_definitions(&expanded_crate))); time(sess.time_passes(), "external crate/lib resolution", @@ -133,7 +134,7 @@ pub fn compile_input(sess: &Session, .read_crates(&dep_graph)); // Lower ast -> hir. - let lcx = LoweringContext::new(sess, Some(&expanded_crate)); + let lcx = LoweringContext::new(sess, Some(&expanded_crate), defs); let hir_forest = &mut time(sess.time_passes(), "lowering ast -> hir", || hir_map::Forest::new(lower_crate(&lcx, &expanded_crate), diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 769449b96d2..0e100f48ac3 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -199,14 +199,9 @@ pub fn run_compiler<'a>(args: &[String], // It is somewhat unfortunate that this is hardwired in - this is forced by // the fact that pretty_print_input requires the session by value. let pretty = callbacks.parse_pretty(&sess, &matches); - match pretty { - Some((ppm, opt_uii)) => { - pretty::pretty_print_input(sess, &cstore, cfg, &input, ppm, opt_uii, ofile); - return (Ok(()), None); - } - None => { - // continue - } + if let Some((ppm, opt_uii)) = pretty { + pretty::pretty_print_input(sess, &cstore, cfg, &input, ppm, opt_uii, ofile); + return (Ok(()), None); } let plugins = sess.opts.debugging_opts.extra_plugins.clone(); diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 2e3a477e048..b1143fd3e84 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -29,6 +29,7 @@ use rustc_borrowck as borrowck; use rustc_borrowck::graphviz as borrowck_dot; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; +use rustc_metadata::creader::LocalCrateReader; use rustc_mir::pretty::write_mir_pretty; use rustc_mir::graphviz::write_mir_graphviz; @@ -43,6 +44,7 @@ use syntax::util::small_vector::SmallVector; use graphviz as dot; +use std::cell::RefCell; use std::fs::File; use std::io::{self, Write}; use std::iter; @@ -719,7 +721,7 @@ pub fn pretty_print_input(sess: Session, let is_expanded = needs_expansion(&ppm); let compute_ast_map = needs_ast_map(&ppm, &opt_uii); let krate = if compute_ast_map { - match driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id[..], None) { + match driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None) { Err(_) => return, Ok(k) => driver::assign_node_ids(&sess, k), } @@ -730,15 +732,18 @@ pub fn pretty_print_input(sess: Session, // There is some twisted, god-forsaken tangle of lifetimes here which makes // the ordering of stuff super-finicky. let mut hir_forest; - let lcx = LoweringContext::new(&sess, Some(&krate)); - let arenas = ty::CtxtArenas::new(); + let mut _defs = None; let dep_graph = DepGraph::new(false); + let arenas = ty::CtxtArenas::new(); let _ignore = dep_graph.in_ignore(); let ast_map = if compute_ast_map { - let defs = hir_map::collect_definitions(&krate); + _defs = Some(RefCell::new(hir_map::collect_definitions(&krate))); + let defs = _defs.as_ref().unwrap(); + LocalCrateReader::new(&sess, &cstore, defs, &krate, &id).read_crates(&dep_graph); + let lcx = LoweringContext::new(&sess, Some(&krate), defs); + hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); - let map = hir_map::map_crate(&mut hir_forest, defs); - Some(map) + Some(hir_map::map_crate(&mut hir_forest, defs)) } else { None }; @@ -751,7 +756,7 @@ pub fn pretty_print_input(sess: Session, .unwrap() .as_bytes() .to_vec(); - let mut rdr = &src[..]; + let mut rdr = &*src; let mut out = Vec::new(); diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index fc12d546288..ce92dd158c9 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -27,8 +27,10 @@ use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::relate::TypeRelation; use rustc::infer::{self, InferOk, InferResult, TypeOrigin}; use rustc_metadata::cstore::CStore; +use rustc_metadata::creader::LocalCrateReader; use rustc::hir::map as hir_map; use rustc::session::{self, config}; +use std::cell::RefCell; use std::rc::Rc; use syntax::ast; use syntax::abi::Abi; @@ -119,13 +121,15 @@ fn test_env(source_string: &str, let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, "test", None) .expect("phase 2 aborted"); - let krate = driver::assign_node_ids(&sess, krate); - let lcx = LoweringContext::new(&sess, Some(&krate)); let dep_graph = DepGraph::new(false); + let krate = driver::assign_node_ids(&sess, krate); + let defs = &RefCell::new(hir_map::collect_definitions(&krate)); + LocalCrateReader::new(&sess, &cstore, defs, &krate, "test_crate").read_crates(&dep_graph); + let lcx = LoweringContext::new(&sess, Some(&krate), defs); let _ignore = dep_graph.in_ignore(); - let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); + let mut hir_forest = &mut hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph.clone()); let arenas = ty::CtxtArenas::new(); - let ast_map = driver::make_map(&sess, &mut hir_forest); + let ast_map = hir_map::map_crate(hir_forest, defs); // run just enough stuff to build a tcx: let lang_items = lang_items::collect_language_items(&sess, &ast_map); diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 49512a5018e..2d6a043e34a 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -1339,7 +1339,7 @@ fn roundtrip(in_item: hir::Item) { fn test_basic() { let cx = mk_ctxt(); let fnia = FakeNodeIdAssigner; - let lcx = LoweringContext::new(&fnia, None); + let lcx = LoweringContext::testing_context(&fnia); roundtrip(lower_item(&lcx, "e_item!(&cx, fn foo() {} ).unwrap())); @@ -1349,7 +1349,7 @@ fn test_basic() { fn test_smalltalk() { let cx = mk_ctxt(); let fnia = FakeNodeIdAssigner; - let lcx = LoweringContext::new(&fnia, None); + let lcx = LoweringContext::testing_context(&fnia); roundtrip(lower_item(&lcx, "e_item!(&cx, fn foo() -> isize { 3 + 4 } // first smalltalk program ever executed. ).unwrap())); @@ -1359,7 +1359,7 @@ fn test_smalltalk() { fn test_more() { let cx = mk_ctxt(); let fnia = FakeNodeIdAssigner; - let lcx = LoweringContext::new(&fnia, None); + let lcx = LoweringContext::testing_context(&fnia); roundtrip(lower_item(&lcx, "e_item!(&cx, fn foo(x: usize, y: usize) -> usize { let z = x + y; @@ -1378,7 +1378,7 @@ fn test_simplification() { } ).unwrap(); let fnia = FakeNodeIdAssigner; - let lcx = LoweringContext::new(&fnia, None); + let lcx = LoweringContext::testing_context(&fnia); let hir_item = lower_item(&lcx, &item); let item_in = InlinedItemRef::Item(&hir_item); let item_out = simplify_ast(item_in); diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 4ba59a3d7eb..635ef4ab358 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -45,7 +45,7 @@ pub struct LocalCrateReader<'a> { cstore: &'a CStore, creader: CrateReader<'a>, krate: &'a ast::Crate, - defintions: &'a hir_map::Definitions, + defintions: &'a RefCell, } pub struct CrateReader<'a> { @@ -59,6 +59,7 @@ pub struct CrateReader<'a> { impl<'a, 'ast> visit::Visitor<'ast> for LocalCrateReader<'a> { fn visit_item(&mut self, a: &'ast ast::Item) { self.process_item(a); + visit::walk_item(self, a); } } @@ -81,6 +82,7 @@ fn should_link(i: &ast::Item) -> bool { !attr::contains_name(&i.attrs, "no_link") } +#[derive(Debug)] struct CrateInfo { ident: String, name: String, @@ -750,7 +752,7 @@ impl<'a> CrateReader<'a> { impl<'a> LocalCrateReader<'a> { pub fn new(sess: &'a Session, cstore: &'a CStore, - defs: &'a hir_map::Definitions, + defs: &'a RefCell, krate: &'a ast::Crate, local_crate_name: &str) -> LocalCrateReader<'a> { @@ -807,9 +809,10 @@ impl<'a> LocalCrateReader<'a> { i.span, PathKind::Crate, true); - let def_id = self.defintions.opt_local_def_id(i.id).unwrap(); - let len = self.defintions.def_path(def_id.index).data.len(); + let defs = self.defintions.borrow(); + let def_id = defs.opt_local_def_id(i.id).unwrap(); + let len = defs.def_path(def_id.index).data.len(); self.creader.update_extern_crate(cnum, ExternCrate { diff --git a/src/librustc_save_analysis/csv_dumper.rs b/src/librustc_save_analysis/csv_dumper.rs index 0e02830db7a..45ec9a97a11 100644 --- a/src/librustc_save_analysis/csv_dumper.rs +++ b/src/librustc_save_analysis/csv_dumper.rs @@ -17,10 +17,10 @@ use super::data::*; use super::dump::Dump; use super::span_utils::SpanUtils; -pub struct CsvDumper<'a, 'b, W: 'b> { +pub struct CsvDumper<'tcx, 'b, W: 'b> { output: &'b mut W, dump_spans: bool, - span: SpanUtils<'a> + span: SpanUtils<'tcx> } impl<'a, 'b, W: Write> CsvDumper<'a, 'b, W> { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 3784c95fe2b..bf6ad703963 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -42,7 +42,7 @@ use syntax::visit::{self, Visitor}; use syntax::print::pprust::{path_to_string, ty_to_string}; use syntax::ptr::P; -use rustc::hir::lowering::{lower_expr, LoweringContext}; +use rustc::hir::lowering::lower_expr; use super::{escape, generated_code, SaveContext, PathCollector}; use super::data::*; @@ -60,12 +60,12 @@ macro_rules! down_cast_data { }; } -pub struct DumpVisitor<'l, 'tcx: 'l, D: 'l> { +pub struct DumpVisitor<'l, 'tcx: 'l, 'll, D: 'll> { save_ctxt: SaveContext<'l, 'tcx>, sess: &'l Session, tcx: &'l TyCtxt<'tcx>, analysis: &'l ty::CrateAnalysis<'l>, - dumper: &'l mut D, + dumper: &'ll mut D, span: SpanUtils<'l>, @@ -77,22 +77,19 @@ pub struct DumpVisitor<'l, 'tcx: 'l, D: 'l> { // one macro use per unique callsite span. mac_defs: HashSet, mac_uses: HashSet, - } -impl <'l, 'tcx, D> DumpVisitor<'l, 'tcx, D> -where D: Dump -{ +impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { pub fn new(tcx: &'l TyCtxt<'tcx>, - lcx: &'l LoweringContext<'l>, + save_ctxt: SaveContext<'l, 'tcx>, analysis: &'l ty::CrateAnalysis<'l>, - dumper: &'l mut D) - -> DumpVisitor<'l, 'tcx, D> { + dumper: &'ll mut D) + -> DumpVisitor<'l, 'tcx, 'll, D> { let span_utils = SpanUtils::new(&tcx.sess); DumpVisitor { sess: &tcx.sess, tcx: tcx, - save_ctxt: SaveContext::from_span_utils(tcx, lcx, span_utils.clone()), + save_ctxt: save_ctxt, analysis: analysis, dumper: dumper, span: span_utils.clone(), @@ -103,7 +100,7 @@ where D: Dump } fn nest(&mut self, scope_id: NodeId, f: F) - where F: FnOnce(&mut DumpVisitor<'l, 'tcx, D>) + where F: FnOnce(&mut DumpVisitor<'l, 'tcx, 'll, D>) { let parent_scope = self.cur_scope; self.cur_scope = scope_id; @@ -982,7 +979,7 @@ where D: Dump } } -impl<'l, 'tcx, 'v, D: Dump + 'l> Visitor<'v> for DumpVisitor<'l, 'tcx, D> { +impl<'v, 'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor<'v> for DumpVisitor<'l, 'tcx, 'll, D> { fn visit_item(&mut self, item: &ast::Item) { use syntax::ast::ItemKind::*; self.process_macro_use(item.span, item.id); diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 4596398c315..9148b53322b 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -73,7 +73,7 @@ pub mod recorder { pub struct SaveContext<'l, 'tcx: 'l> { tcx: &'l TyCtxt<'tcx>, lcx: &'l lowering::LoweringContext<'l>, - span_utils: SpanUtils<'l>, + span_utils: SpanUtils<'tcx>, } macro_rules! option_try( @@ -90,7 +90,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { pub fn from_span_utils(tcx: &'l TyCtxt<'tcx>, lcx: &'l lowering::LoweringContext<'l>, - span_utils: SpanUtils<'l>) + span_utils: SpanUtils<'tcx>) -> SaveContext<'l, 'tcx> { SaveContext { tcx: tcx, @@ -680,7 +680,7 @@ impl<'v> Visitor<'v> for PathCollector { pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>, lcx: &'l lowering::LoweringContext<'l>, krate: &ast::Crate, - analysis: &ty::CrateAnalysis, + analysis: &'l ty::CrateAnalysis<'l>, cratename: &str, odir: Option<&Path>) { let _ignore = tcx.dep_graph.in_ignore(); @@ -726,9 +726,10 @@ pub fn process_crate<'l, 'tcx>(tcx: &'l TyCtxt<'tcx>, }); root_path.pop(); - let utils = SpanUtils::new(&tcx.sess); + let utils: SpanUtils<'tcx> = SpanUtils::new(&tcx.sess); + let save_ctxt = SaveContext::new(tcx, lcx); let mut dumper = CsvDumper::new(&mut output_file, utils); - let mut visitor = DumpVisitor::new(tcx, lcx, analysis, &mut dumper); + let mut visitor = DumpVisitor::new(tcx, save_ctxt, analysis, &mut dumper); // FIXME: we don't write anything! visitor.dump_crate_info(cratename, krate); diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index f410d428177..c64eeb92737 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -26,6 +26,8 @@ use syntax::parse::token::{keywords, Token}; #[derive(Clone)] pub struct SpanUtils<'a> { pub sess: &'a Session, + // FIXME given that we clone SpanUtils all over the place, this err_count is + // probably useless and any logic relying on it is bogus. pub err_count: Cell, } diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index b7c60b8a524..6d1e91a687e 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -22,6 +22,7 @@ use rustc_trans::back::link; use rustc_resolve as resolve; use rustc::hir::lowering::{lower_crate, LoweringContext}; use rustc_metadata::cstore::CStore; +use rustc_metadata::creader::LocalCrateReader; use syntax::{ast, codemap, errors}; use syntax::errors::emitter::ColorConfig; @@ -151,14 +152,18 @@ pub fn run_core(search_paths: SearchPaths, .expect("phase_2_configure_and_expand aborted in rustdoc!"); let krate = driver::assign_node_ids(&sess, krate); + let dep_graph = DepGraph::new(false); + + let defs = &RefCell::new(hir_map::collect_definitions(&krate)); + LocalCrateReader::new(&sess, &cstore, &defs, &krate, &name).read_crates(&dep_graph); + let lcx = LoweringContext::new(&sess, Some(&krate), defs); + // Lower ast -> hir. - let lcx = LoweringContext::new(&sess, Some(&krate)); - let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), DepGraph::new(false)); + let mut hir_forest = hir_map::Forest::new(lower_crate(&lcx, &krate), dep_graph); let arenas = ty::CtxtArenas::new(); - let hir_map = driver::make_map(&sess, &mut hir_forest); + let hir_map = hir_map::map_crate(&mut hir_forest, defs); abort_on_err(driver::phase_3_run_analysis_passes(&sess, - &cstore, hir_map, &arenas, &name, diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 5a7050fb42f..487aac1806e 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -94,15 +94,17 @@ pub fn run(input: &str, "rustdoc-test", None) .expect("phase_2_configure_and_expand aborted in rustdoc!"); let krate = driver::assign_node_ids(&sess, krate); - let lcx = LoweringContext::new(&sess, Some(&krate)); + let dep_graph = DepGraph::new(false); + let defs = &RefCell::new(hir_map::collect_definitions(&krate)); + + let lcx = LoweringContext::new(&sess, Some(&krate), defs); let krate = lower_crate(&lcx, &krate); let opts = scrape_test_config(&krate); - let dep_graph = DepGraph::new(false); let _ignore = dep_graph.in_ignore(); let mut forest = hir_map::Forest::new(krate, dep_graph.clone()); - let map = hir_map::map_crate(&mut forest); + let map = hir_map::map_crate(&mut forest, defs); let ctx = core::DocContext { map: &map, diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index 12cc475f121..86b9c4c81c6 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -20,6 +20,7 @@ extern crate rustc_metadata; extern crate rustc_resolve; #[macro_use] extern crate syntax; +use std::cell::RefCell; use std::ffi::{CStr, CString}; use std::mem::transmute; use std::path::PathBuf; @@ -35,6 +36,7 @@ use rustc::session::build_session; use rustc_driver::{driver, abort_on_err}; use rustc::hir::lowering::{lower_crate, LoweringContext}; use rustc_resolve::MakeGlobMap; +use rustc_metadata::creader::LocalCrateReader; use rustc_metadata::cstore::CStore; use libc::c_void; @@ -237,15 +239,17 @@ fn compile_program(input: &str, sysroot: PathBuf) let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None) .expect("phase_2 returned `None`"); + let dep_graph = DepGraph::new(sess.opts.build_dep_graph); let krate = driver::assign_node_ids(&sess, krate); - let lcx = LoweringContext::new(&sess, Some(&krate)); - let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); + let defs = RefCell::new(ast_map::collect_definitions(&krate)); + LocalCrateReader::new(&sess, &cstore, &defs, &krate, &id).read_crates(&dep_graph); + let lcx = LoweringContext::new(&sess, Some(&krate), &defs); let mut hir_forest = ast_map::Forest::new(lower_crate(&lcx, &krate), dep_graph); let arenas = ty::CtxtArenas::new(); - let ast_map = driver::make_map(&sess, &mut hir_forest); + let ast_map = ast_map::map_crate(&mut hir_forest, &defs); abort_on_err(driver::phase_3_run_analysis_passes( - &sess, &cstore, ast_map, &arenas, &id, + &sess, ast_map, &arenas, &id, MakeGlobMap::No, |tcx, mir_map, analysis, _| { let trans = driver::phase_4_translate_to_llvm(tcx, mir_map.unwrap(), analysis); From 0be3c8c56977c1f0d875461279e00bca7b4e5ebf Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 19 Apr 2016 16:16:40 +1200 Subject: [PATCH 15/15] rebasing --- src/librustc/hir/map/def_collector.rs | 4 ++-- src/librustc_driver/driver.rs | 2 +- src/test/run-make/execution-engine/test.rs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index b2456f4ab87..053d32305be 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -109,9 +109,9 @@ impl<'ast> visit::Visitor<'ast> for DefCollector<'ast> { ItemKind::DefaultImpl(..) | ItemKind::Impl(..) => DefPathData::Impl, ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Trait(..) | - ItemKind::ExternCrate(..) | ItemKind::Mod(..) | ItemKind::ForeignMod(..) | - ItemKind::Ty(..) => + ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::Ty(..) => DefPathData::TypeNs(i.ident.name), + ItemKind::Mod(..) => DefPathData::Module(i.ident.name), ItemKind::Static(..) | ItemKind::Const(..) | ItemKind::Fn(..) => DefPathData::ValueNs(i.ident.name), ItemKind::Mac(..) => DefPathData::MacroDef(i.ident.name), diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index 26422e3194a..5fc2a955c06 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -121,7 +121,7 @@ pub fn compile_input(sess: &Session, Ok(())); let expanded_crate = assign_node_ids(sess, expanded_crate); - let dep_graph = DepGraph::new(sess.opts.build_dep_graph); + let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); // Collect defintions for def ids. let defs = &RefCell::new(time(sess.time_passes(), diff --git a/src/test/run-make/execution-engine/test.rs b/src/test/run-make/execution-engine/test.rs index 86b9c4c81c6..b9a45c09626 100644 --- a/src/test/run-make/execution-engine/test.rs +++ b/src/test/run-make/execution-engine/test.rs @@ -239,7 +239,7 @@ fn compile_program(input: &str, sysroot: PathBuf) let krate = driver::phase_2_configure_and_expand(&sess, &cstore, krate, &id, None) .expect("phase_2 returned `None`"); - let dep_graph = DepGraph::new(sess.opts.build_dep_graph); + let dep_graph = DepGraph::new(sess.opts.build_dep_graph()); let krate = driver::assign_node_ids(&sess, krate); let defs = RefCell::new(ast_map::collect_definitions(&krate)); LocalCrateReader::new(&sess, &cstore, &defs, &krate, &id).read_crates(&dep_graph);