Skip to content

Commit 2cd006d

Browse files
committed
---
yaml --- r: 232730 b: refs/heads/try c: 80b971a h: refs/heads/master v: v3
1 parent e12c843 commit 2cd006d

File tree

14 files changed

+328
-126
lines changed

14 files changed

+328
-126
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
refs/heads/master: edeb4f1c86cbf6af8ef9874d4b3af50f721ea1b8
33
refs/heads/snap-stage3: 1af31d4974e33027a68126fa5a5a3c2c6491824f
4-
refs/heads/try: 424d9c2778062d200b327b4da14528c788e75c45
4+
refs/heads/try: 80b971a9b86cf56eab5a6f707107175d4bf2bbe1
55
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
66
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
77
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try/src/libcore/any.rs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,12 @@
1313
//!
1414
//! `Any` itself can be used to get a `TypeId`, and has more features when used
1515
//! as a trait object. As `&Any` (a borrowed trait object), it has the `is` and
16-
//! `as_ref` methods, to test if the contained value is of a given type, and to
17-
//! get a reference to the inner value as a type. As `&mut Any`, there is also
18-
//! the `as_mut` method, for getting a mutable reference to the inner value.
19-
//! `Box<Any>` adds the `move` method, which will unwrap a `Box<T>` from the
20-
//! object. See the extension traits (`*Ext`) for the full details.
16+
//! `downcast_ref` methods, to test if the contained value is of a given type,
17+
//! and to get a reference to the inner value as a type. As `&mut Any`, there
18+
//! is also the `downcast_mut` method, for getting a mutable reference to the
19+
//! inner value. `Box<Any>` adds the `move` method, which will unwrap a
20+
//! `Box<T>` from the object. See the extension traits (`*Ext`) for the full
21+
//! details.
2122
//!
2223
//! Note that &Any is limited to testing whether a value is of a specified
2324
//! concrete type, and cannot be used to test whether a type implements a trait.

branches/try/src/libcore/iter.rs

Lines changed: 71 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ pub trait Iterator {
184184
fn chain<U>(self, other: U) -> Chain<Self, U::IntoIter> where
185185
Self: Sized, U: IntoIterator<Item=Self::Item>,
186186
{
187-
Chain{a: self, b: other.into_iter(), flag: false}
187+
Chain{a: self, b: other.into_iter(), state: ChainState::Both}
188188
}
189189

190190
/// Creates an iterator that iterates over both this and the specified
@@ -1277,7 +1277,30 @@ impl<I> Iterator for Cycle<I> where I: Clone + Iterator {
12771277
pub struct Chain<A, B> {
12781278
a: A,
12791279
b: B,
1280-
flag: bool,
1280+
state: ChainState,
1281+
}
1282+
1283+
// The iterator protocol specifies that iteration ends with the return value
1284+
// `None` from `.next()` (or `.next_back()`) and it is unspecified what
1285+
// further calls return. The chain adaptor must account for this since it uses
1286+
// two subiterators.
1287+
//
1288+
// It uses three states:
1289+
//
1290+
// - Both: `a` and `b` are remaining
1291+
// - Front: `a` remaining
1292+
// - Back: `b` remaining
1293+
//
1294+
// The fourth state (neither iterator is remaining) only occurs after Chain has
1295+
// returned None once, so we don't need to store this state.
1296+
#[derive(Clone)]
1297+
enum ChainState {
1298+
// both front and back iterator are remaining
1299+
Both,
1300+
// only front is remaining
1301+
Front,
1302+
// only back is remaining
1303+
Back,
12811304
}
12821305

12831306
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1289,42 +1312,58 @@ impl<A, B> Iterator for Chain<A, B> where
12891312

12901313
#[inline]
12911314
fn next(&mut self) -> Option<A::Item> {
1292-
if self.flag {
1293-
self.b.next()
1294-
} else {
1295-
match self.a.next() {
1296-
Some(x) => return Some(x),
1297-
_ => ()
1298-
}
1299-
self.flag = true;
1300-
self.b.next()
1315+
match self.state {
1316+
ChainState::Both => match self.a.next() {
1317+
elt @ Some(..) => return elt,
1318+
None => {
1319+
self.state = ChainState::Back;
1320+
self.b.next()
1321+
}
1322+
},
1323+
ChainState::Front => self.a.next(),
1324+
ChainState::Back => self.b.next(),
13011325
}
13021326
}
13031327

13041328
#[inline]
13051329
fn count(self) -> usize {
1306-
(if !self.flag { self.a.count() } else { 0 }) + self.b.count()
1330+
match self.state {
1331+
ChainState::Both => self.a.count() + self.b.count(),
1332+
ChainState::Front => self.a.count(),
1333+
ChainState::Back => self.b.count(),
1334+
}
13071335
}
13081336

13091337
#[inline]
13101338
fn nth(&mut self, mut n: usize) -> Option<A::Item> {
1311-
if !self.flag {
1312-
for x in self.a.by_ref() {
1313-
if n == 0 {
1314-
return Some(x)
1339+
match self.state {
1340+
ChainState::Both | ChainState::Front => {
1341+
for x in self.a.by_ref() {
1342+
if n == 0 {
1343+
return Some(x)
1344+
}
1345+
n -= 1;
1346+
}
1347+
if let ChainState::Both = self.state {
1348+
self.state = ChainState::Back;
13151349
}
1316-
n -= 1;
13171350
}
1318-
self.flag = true;
1351+
ChainState::Back => {}
1352+
}
1353+
if let ChainState::Back = self.state {
1354+
self.b.nth(n)
1355+
} else {
1356+
None
13191357
}
1320-
self.b.nth(n)
13211358
}
13221359

13231360
#[inline]
13241361
fn last(self) -> Option<A::Item> {
1325-
let a_last = if self.flag { None } else { self.a.last() };
1326-
let b_last = self.b.last();
1327-
b_last.or(a_last)
1362+
match self.state {
1363+
ChainState::Both => self.b.last().or(self.a.last()),
1364+
ChainState::Front => self.a.last(),
1365+
ChainState::Back => self.b.last()
1366+
}
13281367
}
13291368

13301369
#[inline]
@@ -1350,9 +1389,16 @@ impl<A, B> DoubleEndedIterator for Chain<A, B> where
13501389
{
13511390
#[inline]
13521391
fn next_back(&mut self) -> Option<A::Item> {
1353-
match self.b.next_back() {
1354-
Some(x) => Some(x),
1355-
None => self.a.next_back()
1392+
match self.state {
1393+
ChainState::Both => match self.b.next_back() {
1394+
elt @ Some(..) => return elt,
1395+
None => {
1396+
self.state = ChainState::Front;
1397+
self.a.next_back()
1398+
}
1399+
},
1400+
ChainState::Front => self.a.next_back(),
1401+
ChainState::Back => self.b.next_back(),
13561402
}
13571403
}
13581404
}

branches/try/src/libcoretest/iter.rs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,26 @@ fn test_double_ended_chain() {
729729
assert_eq!(it.next_back().unwrap(), &5);
730730
assert_eq!(it.next_back().unwrap(), &7);
731731
assert_eq!(it.next_back(), None);
732+
733+
734+
// test that .chain() is well behaved with an unfused iterator
735+
struct CrazyIterator(bool);
736+
impl CrazyIterator { fn new() -> CrazyIterator { CrazyIterator(false) } }
737+
impl Iterator for CrazyIterator {
738+
type Item = i32;
739+
fn next(&mut self) -> Option<i32> {
740+
if self.0 { Some(99) } else { self.0 = true; None }
741+
}
742+
}
743+
744+
impl DoubleEndedIterator for CrazyIterator {
745+
fn next_back(&mut self) -> Option<i32> {
746+
self.next()
747+
}
748+
}
749+
750+
assert_eq!(CrazyIterator::new().chain(0..10).rev().last(), Some(0));
751+
assert!((0..10).chain(CrazyIterator::new()).rev().any(|i| i == 0));
732752
}
733753

734754
#[test]

branches/try/src/librustc/middle/entry.rs

Lines changed: 36 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -11,20 +11,19 @@
1111

1212
use ast_map;
1313
use session::{config, Session};
14-
use syntax::ast::{Name, NodeId, Item, ItemFn};
14+
use syntax;
15+
use syntax::ast::{NodeId, Item};
1516
use syntax::attr;
1617
use syntax::codemap::Span;
17-
use syntax::parse::token;
18+
use syntax::entry::EntryPointType;
1819
use syntax::visit;
1920
use syntax::visit::Visitor;
2021

21-
struct EntryContext<'a, 'ast: 'a> {
22+
struct EntryContext<'a> {
2223
session: &'a Session,
2324

24-
ast_map: &'a ast_map::Map<'ast>,
25-
26-
// The interned Name for "main".
27-
main_name: Name,
25+
// The current depth in the ast
26+
depth: usize,
2827

2928
// The top-level function called 'main'
3029
main_fn: Option<(NodeId, Span)>,
@@ -40,9 +39,11 @@ struct EntryContext<'a, 'ast: 'a> {
4039
non_main_fns: Vec<(NodeId, Span)> ,
4140
}
4241

43-
impl<'a, 'ast, 'v> Visitor<'v> for EntryContext<'a, 'ast> {
42+
impl<'a, 'v> Visitor<'v> for EntryContext<'a> {
4443
fn visit_item(&mut self, item: &Item) {
44+
self.depth += 1;
4545
find_item(item, self);
46+
self.depth -= 1;
4647
}
4748
}
4849

@@ -63,8 +64,7 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
6364

6465
let mut ctxt = EntryContext {
6566
session: session,
66-
main_name: token::intern("main"),
67-
ast_map: ast_map,
67+
depth: 0,
6868
main_fn: None,
6969
attr_main_fn: None,
7070
start_fn: None,
@@ -77,44 +77,35 @@ pub fn find_entry_point(session: &Session, ast_map: &ast_map::Map) {
7777
}
7878

7979
fn find_item(item: &Item, ctxt: &mut EntryContext) {
80-
match item.node {
81-
ItemFn(..) => {
82-
if item.ident.name == ctxt.main_name {
83-
ctxt.ast_map.with_path(item.id, |path| {
84-
if path.count() == 1 {
85-
// This is a top-level function so can be 'main'
86-
if ctxt.main_fn.is_none() {
87-
ctxt.main_fn = Some((item.id, item.span));
88-
} else {
89-
span_err!(ctxt.session, item.span, E0136,
90-
"multiple 'main' functions");
91-
}
92-
} else {
93-
// This isn't main
94-
ctxt.non_main_fns.push((item.id, item.span));
95-
}
96-
});
80+
match syntax::entry::entry_point_type(item, ctxt.depth) {
81+
EntryPointType::MainNamed => {
82+
if ctxt.main_fn.is_none() {
83+
ctxt.main_fn = Some((item.id, item.span));
84+
} else {
85+
span_err!(ctxt.session, item.span, E0136,
86+
"multiple 'main' functions");
9787
}
98-
99-
if attr::contains_name(&item.attrs, "main") {
100-
if ctxt.attr_main_fn.is_none() {
101-
ctxt.attr_main_fn = Some((item.id, item.span));
102-
} else {
103-
span_err!(ctxt.session, item.span, E0137,
104-
"multiple functions with a #[main] attribute");
105-
}
88+
},
89+
EntryPointType::OtherMain => {
90+
ctxt.non_main_fns.push((item.id, item.span));
91+
},
92+
EntryPointType::MainAttr => {
93+
if ctxt.attr_main_fn.is_none() {
94+
ctxt.attr_main_fn = Some((item.id, item.span));
95+
} else {
96+
span_err!(ctxt.session, item.span, E0137,
97+
"multiple functions with a #[main] attribute");
10698
}
107-
108-
if attr::contains_name(&item.attrs, "start") {
109-
if ctxt.start_fn.is_none() {
110-
ctxt.start_fn = Some((item.id, item.span));
111-
} else {
112-
span_err!(ctxt.session, item.span, E0138,
113-
"multiple 'start' functions");
114-
}
99+
},
100+
EntryPointType::Start => {
101+
if ctxt.start_fn.is_none() {
102+
ctxt.start_fn = Some((item.id, item.span));
103+
} else {
104+
span_err!(ctxt.session, item.span, E0138,
105+
"multiple 'start' functions");
115106
}
116-
}
117-
_ => ()
107+
},
108+
EntryPointType::None => ()
118109
}
119110

120111
visit::walk_item(ctxt, item);

branches/try/src/libstd/collections/mod.rs

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
//!
2626
//! Rust's collections can be grouped into four major categories:
2727
//!
28-
//! * Sequences: `Vec`, `VecDeque`, `LinkedList`, `BitVec`
29-
//! * Maps: `HashMap`, `BTreeMap`, `VecMap`
30-
//! * Sets: `HashSet`, `BTreeSet`, `BitSet`
28+
//! * Sequences: `Vec`, `VecDeque`, `LinkedList`
29+
//! * Maps: `HashMap`, `BTreeMap`
30+
//! * Sets: `HashSet`, `BTreeSet`
3131
//! * Misc: `BinaryHeap`
3232
//!
3333
//! # When Should You Use Which Collection?
@@ -70,22 +70,11 @@
7070
//! * You want to be able to get all of the entries in order on-demand.
7171
//! * You want a sorted map.
7272
//!
73-
//! ### Use a `VecMap` when:
74-
//! * You want a `HashMap` but with known to be small `usize` keys.
75-
//! * You want a `BTreeMap`, but with known to be small `usize` keys.
76-
//!
7773
//! ### Use the `Set` variant of any of these `Map`s when:
7874
//! * You just want to remember which keys you've seen.
7975
//! * There is no meaningful value to associate with your keys.
8076
//! * You just want a set.
8177
//!
82-
//! ### Use a `BitVec` when:
83-
//! * You want to store an unbounded number of booleans in a small space.
84-
//! * You want a bit vector.
85-
//!
86-
//! ### Use a `BitSet` when:
87-
//! * You want a `BitVec`, but want `Set` properties
88-
//!
8978
//! ### Use a `BinaryHeap` when:
9079
//!
9180
//! * You want to store a bunch of elements, but only ever want to process the
@@ -123,31 +112,20 @@
123112
//! | Vec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) |
124113
//! | VecDeque | O(1) | O(min(i, n-i))* | O(min(i, n-i)) | O(m)* | O(min(i, n-i)) |
125114
//! | LinkedList | O(min(i, n-i)) | O(min(i, n-i)) | O(min(i, n-i)) | O(1) | O(min(i, n-i)) |
126-
//! | BitVec | O(1) | O(n-i)* | O(n-i) | O(m)* | O(n-i) |
127115
//!
128116
//! Note that where ties occur, Vec is generally going to be faster than VecDeque, and VecDeque
129-
//! is generally going to be faster than LinkedList. BitVec is not a general purpose collection, and
130-
//! therefore cannot reasonably be compared.
117+
//! is generally going to be faster than LinkedList.
131118
//!
132119
//! ## Maps
133120
//!
134-
//! For Sets, all operations have the cost of the equivalent Map operation. For
135-
//! BitSet,
136-
//! refer to VecMap.
121+
//! For Sets, all operations have the cost of the equivalent Map operation.
137122
//!
138123
//! | | get | insert | remove | predecessor |
139124
//! |----------|-----------|----------|----------|-------------|
140125
//! | HashMap | O(1)~ | O(1)~* | O(1)~ | N/A |
141126
//! | BTreeMap | O(log n) | O(log n) | O(log n) | O(log n) |
142-
//! | VecMap | O(1) | O(1)? | O(1) | O(n) |
143-
//!
144-
//! Note that VecMap is *incredibly* inefficient in terms of space. The O(1)
145-
//! insertion time assumes space for the element is already allocated.
146-
//! Otherwise, a large key may require a massive reallocation, with no direct
147-
//! relation to the number of elements in the collection. VecMap should only be
148-
//! seriously considered for small keys.
149127
//!
150-
//! Note also that BTreeMap's precise performance depends on the value of B.
128+
//! Note that BTreeMap's precise performance depends on the value of B.
151129
//!
152130
//! # Correct and Efficient Usage of Collections
153131
//!

0 commit comments

Comments
 (0)