Skip to content

Commit 0ac6e5a

Browse files
committed
auto merge of #12158 : nikomatsakis/rust/issue-6801-borrowck-closures, r=pcwalton
I factored the commits by affected files, for the most part. The last 7 or 8 contain the meat of the PR. The rest are small changes to closures found in the codebase. Maybe interesting to read to see some of the impact of the rules. r? @pcwalton Fixes #6801
2 parents 2ab248a + 484f0f1 commit 0ac6e5a

File tree

97 files changed

+2967
-2530
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

97 files changed

+2967
-2530
lines changed

src/doc/guide-container.md

+19-13
Original file line numberDiff line numberDiff line change
@@ -181,19 +181,25 @@ never call its underlying iterator again once `None` has been returned:
181181
~~~
182182
let xs = [1,2,3,4,5];
183183
let mut calls = 0;
184-
let it = xs.iter().scan((), |_, x| {
185-
calls += 1;
186-
if *x < 3 { Some(x) } else { None }});
187-
// the iterator will only yield 1 and 2 before returning None
188-
// If we were to call it 5 times, calls would end up as 5, despite only 2 values
189-
// being yielded (and therefore 3 unique calls being made). The fuse() adaptor
190-
// can fix this.
191-
let mut it = it.fuse();
192-
it.next();
193-
it.next();
194-
it.next();
195-
it.next();
196-
it.next();
184+
185+
{
186+
let it = xs.iter().scan((), |_, x| {
187+
calls += 1;
188+
if *x < 3 { Some(x) } else { None }});
189+
190+
// the iterator will only yield 1 and 2 before returning None
191+
// If we were to call it 5 times, calls would end up as 5, despite
192+
// only 2 values being yielded (and therefore 3 unique calls being
193+
// made). The fuse() adaptor can fix this.
194+
195+
let mut it = it.fuse();
196+
it.next();
197+
it.next();
198+
it.next();
199+
it.next();
200+
it.next();
201+
}
202+
197203
assert_eq!(calls, 3);
198204
~~~
199205

src/libgetopts/lib.rs

+37-13
Original file line numberDiff line numberDiff line change
@@ -775,14 +775,13 @@ fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool)
775775
let mut lim = lim;
776776
777777
let mut cont = true;
778-
let slice: || = || { cont = it(ss.slice(slice_start, last_end)) };
779778
780779
// if the limit is larger than the string, lower it to save cycles
781780
if lim >= fake_i {
782781
lim = fake_i;
783782
}
784783
785-
let machine: |(uint, char)| -> bool = |(i, c)| {
784+
let machine: |&mut bool, (uint, char)| -> bool = |cont, (i, c)| {
786785
let whitespace = if ::std::char::is_whitespace(c) { Ws } else { Cr };
787786
let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim };
788787
@@ -794,24 +793,49 @@ fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool)
794793
(B, Cr, OverLim) if (i - last_start + 1) > lim
795794
=> fail!("word starting with {} longer than limit!",
796795
ss.slice(last_start, i + 1)),
797-
(B, Cr, OverLim) => { slice(); slice_start = last_start; B }
798-
(B, Ws, UnderLim) => { last_end = i; C }
799-
(B, Ws, OverLim) => { last_end = i; slice(); A }
800-
801-
(C, Cr, UnderLim) => { last_start = i; B }
802-
(C, Cr, OverLim) => { slice(); slice_start = i; last_start = i; last_end = i; B }
803-
(C, Ws, OverLim) => { slice(); A }
804-
(C, Ws, UnderLim) => { C }
796+
(B, Cr, OverLim) => {
797+
*cont = it(ss.slice(slice_start, last_end));
798+
slice_start = last_start;
799+
B
800+
}
801+
(B, Ws, UnderLim) => {
802+
last_end = i;
803+
C
804+
}
805+
(B, Ws, OverLim) => {
806+
last_end = i;
807+
*cont = it(ss.slice(slice_start, last_end));
808+
A
809+
}
810+
811+
(C, Cr, UnderLim) => {
812+
last_start = i;
813+
B
814+
}
815+
(C, Cr, OverLim) => {
816+
*cont = it(ss.slice(slice_start, last_end));
817+
slice_start = i;
818+
last_start = i;
819+
last_end = i;
820+
B
821+
}
822+
(C, Ws, OverLim) => {
823+
*cont = it(ss.slice(slice_start, last_end));
824+
A
825+
}
826+
(C, Ws, UnderLim) => {
827+
C
828+
}
805829
};
806830

807-
cont
831+
*cont
808832
};
809833

810-
ss.char_indices().advance(|x| machine(x));
834+
ss.char_indices().advance(|x| machine(&mut cont, x));
811835

812836
// Let the automaton 'run out' by supplying trailing whitespace
813837
while cont && match state { B | C => true, A => false } {
814-
machine((fake_i, ' '));
838+
machine(&mut cont, (fake_i, ' '));
815839
fake_i += 1;
816840
}
817841
return cont;

src/libglob/lib.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#[crate_type = "dylib"];
2929
#[license = "MIT/ASL2"];
3030

31+
use std::cell::Cell;
3132
use std::{os, path};
3233
use std::io::fs;
3334
use std::path::is_sep;
@@ -342,22 +343,24 @@ impl Pattern {
342343
}
343344

344345
fn matches_from(&self,
345-
mut prev_char: Option<char>,
346+
prev_char: Option<char>,
346347
mut file: &str,
347348
i: uint,
348349
options: MatchOptions) -> MatchResult {
349350

351+
let prev_char = Cell::new(prev_char);
352+
350353
let require_literal = |c| {
351354
(options.require_literal_separator && is_sep(c)) ||
352355
(options.require_literal_leading_dot && c == '.'
353-
&& is_sep(prev_char.unwrap_or('/')))
356+
&& is_sep(prev_char.get().unwrap_or('/')))
354357
};
355358

356359
for (ti, token) in self.tokens.slice_from(i).iter().enumerate() {
357360
match *token {
358361
AnySequence => {
359362
loop {
360-
match self.matches_from(prev_char, file, i + ti + 1, options) {
363+
match self.matches_from(prev_char.get(), file, i + ti + 1, options) {
361364
SubPatternDoesntMatch => (), // keep trying
362365
m => return m,
363366
}
@@ -370,7 +373,7 @@ impl Pattern {
370373
if require_literal(c) {
371374
return SubPatternDoesntMatch;
372375
}
373-
prev_char = Some(c);
376+
prev_char.set(Some(c));
374377
file = next;
375378
}
376379
}
@@ -400,7 +403,7 @@ impl Pattern {
400403
if !matches {
401404
return SubPatternDoesntMatch;
402405
}
403-
prev_char = Some(c);
406+
prev_char.set(Some(c));
404407
file = next;
405408
}
406409
}

src/librustc/back/link.rs

+21-19
Original file line numberDiff line numberDiff line change
@@ -361,21 +361,23 @@ pub mod write {
361361

362362
let mut llvm_c_strs = ~[];
363363
let mut llvm_args = ~[];
364-
let add = |arg: &str| {
365-
let s = arg.to_c_str();
366-
llvm_args.push(s.with_ref(|p| p));
367-
llvm_c_strs.push(s);
368-
};
369-
add("rustc"); // fake program name
370-
add("-arm-enable-ehabi");
371-
add("-arm-enable-ehabi-descriptors");
372-
if vectorize_loop { add("-vectorize-loops"); }
373-
if vectorize_slp { add("-vectorize-slp"); }
374-
if sess.time_llvm_passes() { add("-time-passes"); }
375-
if sess.print_llvm_passes() { add("-debug-pass=Structure"); }
376-
377-
for arg in sess.opts.cg.llvm_args.iter() {
378-
add(*arg);
364+
{
365+
let add = |arg: &str| {
366+
let s = arg.to_c_str();
367+
llvm_args.push(s.with_ref(|p| p));
368+
llvm_c_strs.push(s);
369+
};
370+
add("rustc"); // fake program name
371+
add("-arm-enable-ehabi");
372+
add("-arm-enable-ehabi-descriptors");
373+
if vectorize_loop { add("-vectorize-loops"); }
374+
if vectorize_slp { add("-vectorize-slp"); }
375+
if sess.time_llvm_passes() { add("-time-passes"); }
376+
if sess.print_llvm_passes() { add("-debug-pass=Structure"); }
377+
378+
for arg in sess.opts.cg.llvm_args.iter() {
379+
add(*arg);
380+
}
379381
}
380382

381383
INIT.doit(|| {
@@ -631,7 +633,7 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
631633

632634
let mut n = ~"_ZN"; // _Z == Begin name-sequence, N == nested
633635

634-
let push = |s: &str| {
636+
let push = |n: &mut ~str, s: &str| {
635637
let sani = sanitize(s);
636638
n.push_str(format!("{}{}", sani.len(), sani));
637639
};
@@ -640,7 +642,7 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
640642
for s in ss.iter() {
641643
match *s {
642644
PathName(s) | PathMod(s) | PathPrettyName(s, _) => {
643-
push(sess.str_of(s))
645+
push(&mut n, sess.str_of(s))
644646
}
645647
}
646648
}
@@ -665,10 +667,10 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
665667
}
666668
}
667669
if hash.len() > 0 {
668-
push(hash);
670+
push(&mut n, hash);
669671
}
670672
match vers {
671-
Some(s) => push(s),
673+
Some(s) => push(&mut n, s),
672674
None => {}
673675
}
674676

src/librustc/front/config.rs

+28-22
Original file line numberDiff line numberDiff line change
@@ -58,16 +58,18 @@ fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::ViewItem)
5858
}
5959

6060
fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
61-
let filtered_items = m.items.iter()
61+
let filtered_items: ~[&@ast::Item] = m.items.iter()
6262
.filter(|&a| item_in_cfg(cx, *a))
63+
.collect();
64+
let flattened_items = filtered_items.move_iter()
6365
.flat_map(|&x| cx.fold_item(x).move_iter())
6466
.collect();
6567
let filtered_view_items = m.view_items.iter().filter_map(|a| {
6668
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
6769
}).collect();
6870
ast::Mod {
6971
view_items: filtered_view_items,
70-
items: filtered_items
72+
items: flattened_items
7173
}
7274
}
7375

@@ -113,23 +115,26 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
113115
ast::ItemStruct(fold_struct(cx, def), generics.clone())
114116
}
115117
ast::ItemEnum(ref def, ref generics) => {
116-
let mut variants = def.variants.iter().map(|c| c.clone()).filter(|m| {
117-
(cx.in_cfg)(m.node.attrs)
118-
}).map(|v| {
119-
match v.node.kind {
120-
ast::TupleVariantKind(..) => v,
121-
ast::StructVariantKind(def) => {
122-
let def = fold_struct(cx, def);
123-
@codemap::Spanned {
124-
node: ast::Variant_ {
125-
kind: ast::StructVariantKind(def),
126-
..v.node.clone()
127-
},
128-
..*v
129-
}
118+
let mut variants = def.variants.iter().map(|c| c.clone()).
119+
filter_map(|v| {
120+
if !(cx.in_cfg)(v.node.attrs) {
121+
None
122+
} else {
123+
Some(match v.node.kind {
124+
ast::TupleVariantKind(..) => v,
125+
ast::StructVariantKind(def) => {
126+
let def = fold_struct(cx, def);
127+
@codemap::Spanned {
128+
node: ast::Variant_ {
129+
kind: ast::StructVariantKind(def),
130+
..v.node.clone()
131+
},
132+
..*v
133+
}
134+
}
135+
})
130136
}
131-
}
132-
});
137+
});
133138
ast::ItemEnum(ast::EnumDef {
134139
variants: variants.collect(),
135140
}, generics.clone())
@@ -165,10 +170,11 @@ fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
165170
}
166171

167172
fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
168-
let resulting_stmts = b.stmts.iter()
169-
.filter(|&a| retain_stmt(cx, *a))
170-
.flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
171-
.collect();
173+
let resulting_stmts: ~[&@ast::Stmt] =
174+
b.stmts.iter().filter(|&a| retain_stmt(cx, *a)).collect();
175+
let resulting_stmts = resulting_stmts.move_iter()
176+
.flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
177+
.collect();
172178
let filtered_view_items = b.view_items.iter().filter_map(|a| {
173179
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
174180
}).collect();

0 commit comments

Comments
 (0)