Skip to content

Commit

Permalink
auto merge of #12158 : nikomatsakis/rust/issue-6801-borrowck-closures…
Browse files Browse the repository at this point in the history
…, 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
  • Loading branch information
bors committed Feb 11, 2014
2 parents 2ab248a + 484f0f1 commit 0ac6e5a
Show file tree
Hide file tree
Showing 97 changed files with 2,967 additions and 2,530 deletions.
32 changes: 19 additions & 13 deletions src/doc/guide-container.md
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,25 @@ never call its underlying iterator again once `None` has been returned:
~~~
let xs = [1,2,3,4,5];
let mut calls = 0;
let it = xs.iter().scan((), |_, x| {
calls += 1;
if *x < 3 { Some(x) } else { None }});
// the iterator will only yield 1 and 2 before returning None
// If we were to call it 5 times, calls would end up as 5, despite only 2 values
// being yielded (and therefore 3 unique calls being made). The fuse() adaptor
// can fix this.
let mut it = it.fuse();
it.next();
it.next();
it.next();
it.next();
it.next();

{
let it = xs.iter().scan((), |_, x| {
calls += 1;
if *x < 3 { Some(x) } else { None }});

// the iterator will only yield 1 and 2 before returning None
// If we were to call it 5 times, calls would end up as 5, despite
// only 2 values being yielded (and therefore 3 unique calls being
// made). The fuse() adaptor can fix this.

let mut it = it.fuse();
it.next();
it.next();
it.next();
it.next();
it.next();
}

assert_eq!(calls, 3);
~~~
Expand Down
50 changes: 37 additions & 13 deletions src/libgetopts/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -775,14 +775,13 @@ fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool)
let mut lim = lim;
let mut cont = true;
let slice: || = || { cont = it(ss.slice(slice_start, last_end)) };
// if the limit is larger than the string, lower it to save cycles
if lim >= fake_i {
lim = fake_i;
}
let machine: |(uint, char)| -> bool = |(i, c)| {
let machine: |&mut bool, (uint, char)| -> bool = |cont, (i, c)| {
let whitespace = if ::std::char::is_whitespace(c) { Ws } else { Cr };
let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim };
Expand All @@ -794,24 +793,49 @@ fn each_split_within<'a>(ss: &'a str, lim: uint, it: |&'a str| -> bool)
(B, Cr, OverLim) if (i - last_start + 1) > lim
=> fail!("word starting with {} longer than limit!",
ss.slice(last_start, i + 1)),
(B, Cr, OverLim) => { slice(); slice_start = last_start; B }
(B, Ws, UnderLim) => { last_end = i; C }
(B, Ws, OverLim) => { last_end = i; slice(); A }

(C, Cr, UnderLim) => { last_start = i; B }
(C, Cr, OverLim) => { slice(); slice_start = i; last_start = i; last_end = i; B }
(C, Ws, OverLim) => { slice(); A }
(C, Ws, UnderLim) => { C }
(B, Cr, OverLim) => {
*cont = it(ss.slice(slice_start, last_end));
slice_start = last_start;
B
}
(B, Ws, UnderLim) => {
last_end = i;
C
}
(B, Ws, OverLim) => {
last_end = i;
*cont = it(ss.slice(slice_start, last_end));
A
}

(C, Cr, UnderLim) => {
last_start = i;
B
}
(C, Cr, OverLim) => {
*cont = it(ss.slice(slice_start, last_end));
slice_start = i;
last_start = i;
last_end = i;
B
}
(C, Ws, OverLim) => {
*cont = it(ss.slice(slice_start, last_end));
A
}
(C, Ws, UnderLim) => {
C
}
};

cont
*cont
};

ss.char_indices().advance(|x| machine(x));
ss.char_indices().advance(|x| machine(&mut cont, x));

// Let the automaton 'run out' by supplying trailing whitespace
while cont && match state { B | C => true, A => false } {
machine((fake_i, ' '));
machine(&mut cont, (fake_i, ' '));
fake_i += 1;
}
return cont;
Expand Down
13 changes: 8 additions & 5 deletions src/libglob/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#[crate_type = "dylib"];
#[license = "MIT/ASL2"];

use std::cell::Cell;
use std::{os, path};
use std::io::fs;
use std::path::is_sep;
Expand Down Expand Up @@ -342,22 +343,24 @@ impl Pattern {
}

fn matches_from(&self,
mut prev_char: Option<char>,
prev_char: Option<char>,
mut file: &str,
i: uint,
options: MatchOptions) -> MatchResult {

let prev_char = Cell::new(prev_char);

let require_literal = |c| {
(options.require_literal_separator && is_sep(c)) ||
(options.require_literal_leading_dot && c == '.'
&& is_sep(prev_char.unwrap_or('/')))
&& is_sep(prev_char.get().unwrap_or('/')))
};

for (ti, token) in self.tokens.slice_from(i).iter().enumerate() {
match *token {
AnySequence => {
loop {
match self.matches_from(prev_char, file, i + ti + 1, options) {
match self.matches_from(prev_char.get(), file, i + ti + 1, options) {
SubPatternDoesntMatch => (), // keep trying
m => return m,
}
Expand All @@ -370,7 +373,7 @@ impl Pattern {
if require_literal(c) {
return SubPatternDoesntMatch;
}
prev_char = Some(c);
prev_char.set(Some(c));
file = next;
}
}
Expand Down Expand Up @@ -400,7 +403,7 @@ impl Pattern {
if !matches {
return SubPatternDoesntMatch;
}
prev_char = Some(c);
prev_char.set(Some(c));
file = next;
}
}
Expand Down
40 changes: 21 additions & 19 deletions src/librustc/back/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -361,21 +361,23 @@ pub mod write {

let mut llvm_c_strs = ~[];
let mut llvm_args = ~[];
let add = |arg: &str| {
let s = arg.to_c_str();
llvm_args.push(s.with_ref(|p| p));
llvm_c_strs.push(s);
};
add("rustc"); // fake program name
add("-arm-enable-ehabi");
add("-arm-enable-ehabi-descriptors");
if vectorize_loop { add("-vectorize-loops"); }
if vectorize_slp { add("-vectorize-slp"); }
if sess.time_llvm_passes() { add("-time-passes"); }
if sess.print_llvm_passes() { add("-debug-pass=Structure"); }

for arg in sess.opts.cg.llvm_args.iter() {
add(*arg);
{
let add = |arg: &str| {
let s = arg.to_c_str();
llvm_args.push(s.with_ref(|p| p));
llvm_c_strs.push(s);
};
add("rustc"); // fake program name
add("-arm-enable-ehabi");
add("-arm-enable-ehabi-descriptors");
if vectorize_loop { add("-vectorize-loops"); }
if vectorize_slp { add("-vectorize-slp"); }
if sess.time_llvm_passes() { add("-time-passes"); }
if sess.print_llvm_passes() { add("-debug-pass=Structure"); }

for arg in sess.opts.cg.llvm_args.iter() {
add(*arg);
}
}

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

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

let push = |s: &str| {
let push = |n: &mut ~str, s: &str| {
let sani = sanitize(s);
n.push_str(format!("{}{}", sani.len(), sani));
};
Expand All @@ -640,7 +642,7 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
for s in ss.iter() {
match *s {
PathName(s) | PathMod(s) | PathPrettyName(s, _) => {
push(sess.str_of(s))
push(&mut n, sess.str_of(s))
}
}
}
Expand All @@ -665,10 +667,10 @@ pub fn mangle(sess: Session, ss: ast_map::Path,
}
}
if hash.len() > 0 {
push(hash);
push(&mut n, hash);
}
match vers {
Some(s) => push(s),
Some(s) => push(&mut n, s),
None => {}
}

Expand Down
50 changes: 28 additions & 22 deletions src/librustc/front/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,18 @@ fn filter_view_item<'r>(cx: &Context, view_item: &'r ast::ViewItem)
}

fn fold_mod(cx: &mut Context, m: &ast::Mod) -> ast::Mod {
let filtered_items = m.items.iter()
let filtered_items: ~[&@ast::Item] = m.items.iter()
.filter(|&a| item_in_cfg(cx, *a))
.collect();
let flattened_items = filtered_items.move_iter()
.flat_map(|&x| cx.fold_item(x).move_iter())
.collect();
let filtered_view_items = m.view_items.iter().filter_map(|a| {
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
}).collect();
ast::Mod {
view_items: filtered_view_items,
items: filtered_items
items: flattened_items
}
}

Expand Down Expand Up @@ -113,23 +115,26 @@ fn fold_item_underscore(cx: &mut Context, item: &ast::Item_) -> ast::Item_ {
ast::ItemStruct(fold_struct(cx, def), generics.clone())
}
ast::ItemEnum(ref def, ref generics) => {
let mut variants = def.variants.iter().map(|c| c.clone()).filter(|m| {
(cx.in_cfg)(m.node.attrs)
}).map(|v| {
match v.node.kind {
ast::TupleVariantKind(..) => v,
ast::StructVariantKind(def) => {
let def = fold_struct(cx, def);
@codemap::Spanned {
node: ast::Variant_ {
kind: ast::StructVariantKind(def),
..v.node.clone()
},
..*v
}
let mut variants = def.variants.iter().map(|c| c.clone()).
filter_map(|v| {
if !(cx.in_cfg)(v.node.attrs) {
None
} else {
Some(match v.node.kind {
ast::TupleVariantKind(..) => v,
ast::StructVariantKind(def) => {
let def = fold_struct(cx, def);
@codemap::Spanned {
node: ast::Variant_ {
kind: ast::StructVariantKind(def),
..v.node.clone()
},
..*v
}
}
})
}
}
});
});
ast::ItemEnum(ast::EnumDef {
variants: variants.collect(),
}, generics.clone())
Expand Down Expand Up @@ -165,10 +170,11 @@ fn retain_stmt(cx: &Context, stmt: @ast::Stmt) -> bool {
}

fn fold_block(cx: &mut Context, b: ast::P<ast::Block>) -> ast::P<ast::Block> {
let resulting_stmts = b.stmts.iter()
.filter(|&a| retain_stmt(cx, *a))
.flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
.collect();
let resulting_stmts: ~[&@ast::Stmt] =
b.stmts.iter().filter(|&a| retain_stmt(cx, *a)).collect();
let resulting_stmts = resulting_stmts.move_iter()
.flat_map(|&stmt| cx.fold_stmt(stmt).move_iter())
.collect();
let filtered_view_items = b.view_items.iter().filter_map(|a| {
filter_view_item(cx, a).map(|x| cx.fold_view_item(x))
}).collect();
Expand Down
Loading

0 comments on commit 0ac6e5a

Please sign in to comment.