auto merge of #20363 : japaric/rust/moar-uc, r=nmatsakis

The the last argument of the `ItemDecorator::expand` method has changed to `Box<FnMut>`. Syntax extensions will break.

[breaking-change]

---

This PR removes pretty much all the remaining uses of boxed closures from the libraries. There are still boxed closures under the `test` directory, but I think those should be removed or replaced with unboxed closures at the same time we remove boxed closures from the language.

In a few places I had to do some contortions (see the first commit for an example) to work around issue #19596. I have marked those workarounds with FIXMEs. In the future when `&mut F where F: FnMut` implements the `FnMut` trait, we should be able to remove those workarounds. I've take care to avoid placing the workaround functions in the public API.

Since `let f = || {}` always gets type checked as a boxed closure, I have explictly annotated those closures (with e.g. `|&:| {}`) to force the compiler to type check them as unboxed closures.

Instead of removing the type aliases (like `GetCrateDataCb`), I could have replaced them with newtypes. But this seemed like overcomplicating things for little to no gain.

I think we should be able to remove the boxed closures from the languge after this PR lands. (I'm being optimistic here)

r? @alexcrichton or @aturon 
cc @nikomatsakis
This commit is contained in:
bors 2015-01-01 04:01:02 +00:00
commit 47b8479e73
59 changed files with 249 additions and 225 deletions

View File

@ -202,7 +202,7 @@ impl<'a> Iterator<char> for Decompositions<'a> {
let buffer = &mut self.buffer;
let sorted = &mut self.sorted;
{
let callback = |d| {
let callback = |&mut: d| {
let class =
unicode::char::canonical_combining_class(d);
if class == 0 && !*sorted {

View File

@ -225,10 +225,10 @@ pub fn float_to_str_bytes_common<T: Float, U, F>(
// cut off the one extra digit, and depending on its value
// round the remaining ones.
if limit_digits && dig == digit_count {
let ascii2value = |chr: u8| {
let ascii2value = |&: chr: u8| {
(chr as char).to_digit(radix).unwrap()
};
let value2ascii = |val: uint| {
let value2ascii = |&: val: uint| {
char::from_digit(val, radix).unwrap() as u8
};

View File

@ -398,7 +398,7 @@ impl<'a> Formatter<'a> {
}
// Writes the sign if it exists, and then the prefix if it was requested
let write_prefix = |f: &mut Formatter| {
let write_prefix = |&: f: &mut Formatter| {
for c in sign.into_iter() {
let mut b = [0, ..4];
let n = c.encode_utf8(&mut b).unwrap_or(0);

View File

@ -875,7 +875,7 @@ fn each_split_within<F>(ss: &str, lim: uint, mut it: F) -> bool where
lim = fake_i;
}
let machine: |&mut bool, (uint, char)| -> bool = |cont, (i, c)| {
let mut machine = |&mut: cont: &mut bool, (i, c): (uint, char)| -> bool {
let whitespace = if c.is_whitespace() { Ws } else { Cr };
let limit = if (i - slice_start + 1) <= lim { UnderLim } else { OverLim };

View File

@ -177,7 +177,7 @@ fn extract_crate_info(e: &Env, i: &ast::ViewItem) -> Option<CrateInfo> {
}
pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option<Span>) {
let err = |s: &str| {
let err = |&: s: &str| {
match (sp, sess) {
(_, None) => panic!("{}", s),
(Some(sp), Some(sess)) => sess.span_err(sp, s),

View File

@ -62,7 +62,7 @@ pub fn each_child_of_item<F>(cstore: &cstore::CStore,
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
{
let crate_data = cstore.get_crate_data(def_id.krate);
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
let get_crate_data = |&mut: cnum| {
cstore.get_crate_data(cnum)
};
decoder::each_child_of_item(cstore.intr.clone(),
@ -79,7 +79,7 @@ pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
F: FnMut(decoder::DefLike, ast::Name, ast::Visibility),
{
let crate_data = cstore.get_crate_data(cnum);
let get_crate_data: decoder::GetCrateDataCb = |cnum| {
let get_crate_data = |&mut: cnum| {
cstore.get_crate_data(cnum)
};
decoder::each_top_level_item_of_crate(cstore.intr.clone(),

View File

@ -487,14 +487,13 @@ pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
})
}
pub type GetCrateDataCb<'a> = |ast::CrateNum|: 'a -> Rc<crate_metadata>;
fn each_child_of_item_or_crate<F>(intr: Rc<IdentInterner>,
cdata: Cmd,
item_doc: rbml::Doc,
get_crate_data: GetCrateDataCb,
mut callback: F) where
fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
cdata: Cmd,
item_doc: rbml::Doc,
mut get_crate_data: G,
mut callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
{
// Iterate over all children.
let _ = reader::tagged_docs(item_doc, tag_mod_child, |child_info_doc| {
@ -608,12 +607,13 @@ fn each_child_of_item_or_crate<F>(intr: Rc<IdentInterner>,
}
/// Iterates over each child of the given item.
pub fn each_child_of_item<F>(intr: Rc<IdentInterner>,
cdata: Cmd,
id: ast::NodeId,
get_crate_data: GetCrateDataCb,
callback: F) where
pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
cdata: Cmd,
id: ast::NodeId,
get_crate_data: G,
callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
{
// Find the item.
let root_doc = rbml::Doc::new(cdata.data());
@ -631,11 +631,12 @@ pub fn each_child_of_item<F>(intr: Rc<IdentInterner>,
}
/// Iterates over all the top-level crate items.
pub fn each_top_level_item_of_crate<F>(intr: Rc<IdentInterner>,
cdata: Cmd,
get_crate_data: GetCrateDataCb,
callback: F) where
pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
cdata: Cmd,
get_crate_data: G,
callback: F) where
F: FnMut(DefLike, ast::Name, ast::Visibility),
G: FnMut(ast::CrateNum) -> Rc<crate_metadata>,
{
let root_doc = rbml::Doc::new(cdata.data());
let misc_info_doc = reader::get_doc(root_doc, tag_misc_info);

View File

@ -1418,7 +1418,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_parent_sort(rbml_w, 't');
let trait_item = &ms[i];
let encode_trait_item = |rbml_w: &mut Encoder| {
let encode_trait_item = |&: rbml_w: &mut Encoder| {
// If this is a static method, we've already
// encoded this.
if is_nonstatic_method {

View File

@ -30,10 +30,6 @@ pub enum FileMatch {
// FIXME (#2658): I'm not happy how this module turned out. Should
// probably just be folded into cstore.
/// Functions with type `pick` take a parent directory as well as
/// a file found in that directory.
pub type pick<'a> = |path: &Path|: 'a -> FileMatch;
pub struct FileSearch<'a> {
pub sysroot: &'a Path,
pub search_paths: &'a SearchPaths,
@ -95,7 +91,7 @@ impl<'a> FileSearch<'a> {
make_target_lib_path(self.sysroot, self.triple)
}
pub fn search(&self, pick: pick) {
pub fn search<F>(&self, mut pick: F) where F: FnMut(&Path) -> FileMatch {
self.for_each_lib_search_path(|lib_search_path| {
debug!("searching {}", lib_search_path.display());
match fs::readdir(lib_search_path) {

View File

@ -185,7 +185,7 @@ fn check_expr(v: &mut CheckCrateVisitor, e: &ast::Expr) -> bool {
ast::ExprBlock(ref block) => {
// Check all statements in the block
for stmt in block.stmts.iter() {
let block_span_err = |span|
let block_span_err = |&: span|
span_err!(v.tcx.sess, span, E0016,
"blocks in constants are limited to items and \
tail expressions");

View File

@ -1012,7 +1012,7 @@ fn check_legality_of_move_bindings(cx: &MatchCheckCtxt,
})
}
let check_move: |&Pat, Option<&Pat>| = |p, sub| {
let check_move = |&: p: &Pat, sub: Option<&Pat>| {
// check legality of moving out of the enum
// x @ Foo(..) is legal, but x @ Foo(y) isn't.

View File

@ -136,7 +136,7 @@ impl<'a, 'tcx> ConstraintGraph<'a, 'tcx> {
let mut i = 0;
let mut node_ids = FnvHashMap::new();
{
let add_node = |node| {
let mut add_node = |&mut : node| {
if let Vacant(e) = node_ids.entry(node) {
e.set(i);
i += 1;

View File

@ -1122,11 +1122,15 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
})
}
// FIXME(#19596) unbox `op`
pub fn cat_pattern(&self,
cmt: cmt<'tcx>,
pat: &ast::Pat,
op: |&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat|)
pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) where
F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat),
{
self.cat_pattern_(cmt, pat, &mut op)
}
// FIXME(#19596) This is a workaround, but there should be a better way to do this
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F) where
F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat),
{
// Here, `cmt` is the categorization for the value being
// matched and pat is the pattern it is being matched against.
@ -1177,7 +1181,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
pat.id, pprust::pat_to_string(pat),
cmt.repr(self.tcx()));
op(self, cmt.clone(), pat);
(*op)(self, cmt.clone(), pat);
let def_map = self.tcx().def_map.borrow();
let opt_def = def_map.get(&pat.id);
@ -1214,7 +1218,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i)));
self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z));
self.cat_pattern_(subcmt, &**subpat, op);
}
}
Some(&def::DefStruct(..)) => {
@ -1224,13 +1228,12 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
self.cat_imm_interior(
pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i)));
self.cat_pattern(cmt_field, &**subpat,
|x,y,z| op(x,y,z));
self.cat_pattern_(cmt_field, &**subpat, op);
}
}
Some(&def::DefConst(..)) => {
for subpat in subpats.iter() {
self.cat_pattern(cmt.clone(), &**subpat, |x,y,z| op(x,y,z));
self.cat_pattern_(cmt.clone(), &**subpat, op);
}
}
_ => {
@ -1242,7 +1245,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
}
ast::PatIdent(_, _, Some(ref subpat)) => {
self.cat_pattern(cmt, &**subpat, op);
self.cat_pattern_(cmt, &**subpat, op);
}
ast::PatIdent(_, _, None) => {
@ -1254,7 +1257,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
for fp in field_pats.iter() {
let field_ty = self.pat_ty(&*fp.node.pat); // see (*2)
let cmt_field = self.cat_field(pat, cmt.clone(), fp.node.ident.name, field_ty);
self.cat_pattern(cmt_field, &*fp.node.pat, |x,y,z| op(x,y,z));
self.cat_pattern_(cmt_field, &*fp.node.pat, op);
}
}
@ -1266,29 +1269,28 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
self.cat_imm_interior(
pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i)));
self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z));
self.cat_pattern_(subcmt, &**subpat, op);
}
}
ast::PatBox(ref subpat) | ast::PatRegion(ref subpat) => {
// @p1, ~p1, ref p1
let subcmt = self.cat_deref(pat, cmt, 0, false);
self.cat_pattern(subcmt, &**subpat, op);
self.cat_pattern_(subcmt, &**subpat, op);
}
ast::PatVec(ref before, ref slice, ref after) => {
let elt_cmt = self.cat_index(pat, self.deref_vec(pat, cmt));
for before_pat in before.iter() {
self.cat_pattern(elt_cmt.clone(), &**before_pat,
|x,y,z| op(x,y,z));
self.cat_pattern_(elt_cmt.clone(), &**before_pat, op);
}
for slice_pat in slice.iter() {
let slice_ty = self.pat_ty(&**slice_pat);
let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
self.cat_pattern(slice_cmt, &**slice_pat, |x,y,z| op(x,y,z));
self.cat_pattern_(slice_cmt, &**slice_pat, op);
}
for after_pat in after.iter() {
self.cat_pattern(elt_cmt.clone(), &**after_pat, |x,y,z| op(x,y,z));
self.cat_pattern_(elt_cmt.clone(), &**after_pat, op);
}
}

View File

@ -749,7 +749,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
fn check_path(&mut self, span: Span, path_id: ast::NodeId, path: &ast::Path) {
debug!("privacy - path {}", self.nodestr(path_id));
let orig_def = self.tcx.def_map.borrow()[path_id].clone();
let ck = |tyname: &str| {
let ck = |&: tyname: &str| {
let ck_public = |def: ast::DefId| {
let name = token::get_ident(path.segments.last().unwrap().identifier);
let origdid = orig_def.def_id();
@ -921,7 +921,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivacyVisitor<'a, 'tcx> {
}
}
ast::ExprPath(..) => {
let guard = |did: ast::DefId| {
let guard = |&: did: ast::DefId| {
let fields = ty::lookup_struct_fields(self.tcx, did);
let any_priv = fields.iter().any(|f| {
f.vis != ast::Public && (
@ -1126,7 +1126,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
/// later on down the road...
fn check_sane_privacy(&self, item: &ast::Item) {
let tcx = self.tcx;
let check_inherited = |sp: Span, vis: ast::Visibility, note: &str| {
let check_inherited = |&: sp: Span, vis: ast::Visibility, note: &str| {
if vis != ast::Inherited {
tcx.sess.span_err(sp, "unnecessary visibility qualifier");
if note.len() > 0 {
@ -1206,7 +1206,7 @@ impl<'a, 'tcx> SanePrivacyVisitor<'a, 'tcx> {
tcx.sess.span_err(sp, "visibility has no effect inside functions");
}
}
let check_struct = |def: &ast::StructDef| {
let check_struct = |&: def: &ast::StructDef| {
for f in def.fields.iter() {
match f.node.kind {
ast::NamedField(_, p) => check_inherited(tcx, f.span, p),

View File

@ -488,7 +488,7 @@ fn resolve_expr(visitor: &mut RegionResolutionVisitor, expr: &ast::Expr) {
{
let region_maps = &mut visitor.region_maps;
let terminating = |id| {
let terminating = |&: id| {
let scope = CodeExtent::from_node_id(id);
region_maps.mark_as_terminating_scope(scope)
};

View File

@ -2812,49 +2812,53 @@ pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where
maybe_walk_ty(ty, |ty| { f(ty); true });
}
// FIXME(#19596) unbox `f`
pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) {
if !f(ty) {
return;
}
match ty.sty {
ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_str | ty_infer(_) | ty_param(_) | ty_err => {}
ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty(ty, f),
ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
maybe_walk_ty(tm.ty, f);
pub fn maybe_walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where F: FnMut(Ty<'tcx>) -> bool {
// FIXME(#19596) This is a workaround, but there should be a better way to do this
fn maybe_walk_ty_<'tcx, F>(ty: Ty<'tcx>, f: &mut F) where F: FnMut(Ty<'tcx>) -> bool {
if !(*f)(ty) {
return;
}
ty_trait(box TyTrait { ref principal, .. }) => {
for subty in principal.0.substs.types.iter() {
maybe_walk_ty(*subty, |x| f(x));
match ty.sty {
ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_str | ty_infer(_) | ty_param(_) | ty_err => {}
ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty_(ty, f),
ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
maybe_walk_ty_(tm.ty, f);
}
}
ty_projection(ProjectionTy { ref trait_ref, .. }) => {
for subty in trait_ref.substs.types.iter() {
maybe_walk_ty(*subty, |x| f(x));
ty_trait(box TyTrait { ref principal, .. }) => {
for subty in principal.0.substs.types.iter() {
maybe_walk_ty_(*subty, f);
}
}
}
ty_enum(_, ref substs) |
ty_struct(_, ref substs) |
ty_unboxed_closure(_, _, ref substs) => {
for subty in substs.types.iter() {
maybe_walk_ty(*subty, |x| f(x));
ty_projection(ProjectionTy { ref trait_ref, .. }) => {
for subty in trait_ref.substs.types.iter() {
maybe_walk_ty_(*subty, f);
}
}
}
ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } }
ty_bare_fn(_, ref ft) => {
for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
if let ty::FnConverging(output) = ft.sig.0.output {
maybe_walk_ty(output, f);
ty_enum(_, ref substs) |
ty_struct(_, ref substs) |
ty_unboxed_closure(_, _, ref substs) => {
for subty in substs.types.iter() {
maybe_walk_ty_(*subty, f);
}
}
}
ty_closure(ref ft) => {
for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); }
if let ty::FnConverging(output) = ft.sig.0.output {
maybe_walk_ty(output, f);
ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty_(*tt, f); } }
ty_bare_fn(_, ref ft) => {
for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); }
if let ty::FnConverging(output) = ft.sig.0.output {
maybe_walk_ty_(output, f);
}
}
ty_closure(ref ft) => {
for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); }
if let ty::FnConverging(output) = ft.sig.0.output {
maybe_walk_ty_(output, f);
}
}
}
}
maybe_walk_ty_(ty, &mut f);
}
// Folds types from the bottom up.
@ -6155,7 +6159,7 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
macro_rules! byte( ($b:expr) => { ($b as u8).hash(state) } );
macro_rules! hash( ($e:expr) => { $e.hash(state) } );
let region = |state: &mut sip::SipState, r: Region| {
let region = |&: state: &mut sip::SipState, r: Region| {
match r {
ReStatic => {}
ReLateBound(db, BrAnon(i)) => {
@ -6172,7 +6176,7 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
}
}
};
let did = |state: &mut sip::SipState, did: DefId| {
let did = |&: state: &mut sip::SipState, did: DefId| {
let h = if ast_util::is_local(did) {
svh.clone()
} else {
@ -6181,10 +6185,10 @@ pub fn hash_crate_independent<'tcx>(tcx: &ctxt<'tcx>, ty: Ty<'tcx>, svh: &Svh) -
h.as_str().hash(state);
did.node.hash(state);
};
let mt = |state: &mut sip::SipState, mt: mt| {
let mt = |&: state: &mut sip::SipState, mt: mt| {
mt.mutbl.hash(state);
};
let fn_sig = |state: &mut sip::SipState, sig: &Binder<FnSig<'tcx>>| {
let fn_sig = |&: state: &mut sip::SipState, sig: &Binder<FnSig<'tcx>>| {
let sig = anonymize_late_bound_regions(tcx, sig);
for a in sig.inputs.iter() { helper(tcx, *a, svh, state); }
if let ty::FnConverging(output) = sig.output {

View File

@ -217,7 +217,7 @@ impl Target {
let handler = diagnostic::default_handler(diagnostic::Auto, None);
let get_req_field = |name: &str| {
let get_req_field = |&: name: &str| {
match obj.find(name)
.map(|s| s.as_string())
.and_then(|os| os.map(|s| s.to_string())) {

View File

@ -44,7 +44,7 @@ enum Fragment {
impl Fragment {
fn loan_path_repr<'tcx>(&self, move_data: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) -> String {
let repr = |mpi| move_data.path_loan_path(mpi).repr(tcx);
let repr = |&: mpi| move_data.path_loan_path(mpi).repr(tcx);
match *self {
Just(mpi) => repr(mpi),
AllButOneFrom(mpi) => format!("$(allbutone {})", repr(mpi)),
@ -54,7 +54,7 @@ impl Fragment {
fn loan_path_user_string<'tcx>(&self,
move_data: &MoveData<'tcx>,
tcx: &ty::ctxt<'tcx>) -> String {
let user_string = |mpi| move_data.path_loan_path(mpi).user_string(tcx);
let user_string = |&: mpi| move_data.path_loan_path(mpi).user_string(tcx);
match *self {
Just(mpi) => user_string(mpi),
AllButOneFrom(mpi) => format!("$(allbutone {})", user_string(mpi)),
@ -140,9 +140,9 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
if !span_err && !print { return; }
let instrument_all_paths = |kind, vec_rc: &Vec<MovePathIndex>| {
let instrument_all_paths = |&: kind, vec_rc: &Vec<MovePathIndex>| {
for (i, mpi) in vec_rc.iter().enumerate() {
let render = || this.path_loan_path(*mpi).user_string(tcx);
let render = |&:| this.path_loan_path(*mpi).user_string(tcx);
if span_err {
tcx.sess.span_err(sp, format!("{}: `{}`", kind, render())[]);
}
@ -152,9 +152,9 @@ pub fn instrument_move_fragments<'tcx>(this: &MoveData<'tcx>,
}
};
let instrument_all_fragments = |kind, vec_rc: &Vec<Fragment>| {
let instrument_all_fragments = |&: kind, vec_rc: &Vec<Fragment>| {
for (i, f) in vec_rc.iter().enumerate() {
let render = || f.loan_path_user_string(this, tcx);
let render = |&:| f.loan_path_user_string(this, tcx);
if span_err {
tcx.sess.span_err(sp, format!("{}: `{}`", kind, render())[]);
}
@ -187,11 +187,11 @@ pub fn fixup_fragment_sets<'tcx>(this: &MoveData<'tcx>, tcx: &ty::ctxt<'tcx>) {
let mut moved = mem::replace(&mut fragments.moved_leaf_paths, vec![]);
let mut assigned = mem::replace(&mut fragments.assigned_leaf_paths, vec![]);
let path_lps = |mpis: &[MovePathIndex]| -> Vec<String> {
let path_lps = |&: mpis: &[MovePathIndex]| -> Vec<String> {
mpis.iter().map(|mpi| this.path_loan_path(*mpi).repr(tcx)).collect()
};
let frag_lps = |fs: &[Fragment]| -> Vec<String> {
let frag_lps = |&: fs: &[Fragment]| -> Vec<String> {
fs.iter().map(|f| f.loan_path_repr(this, tcx)).collect()
};
@ -344,7 +344,7 @@ fn add_fragment_siblings_for_extension<'tcx>(this: &MoveData<'tcx>,
Rc<LoanPath<'tcx>>)>) {
let parent_ty = parent_lp.to_type();
let add_fragment_sibling_local = |field_name, variant_did| {
let mut add_fragment_sibling_local = |&mut : field_name, variant_did| {
add_fragment_sibling_core(
this, tcx, gathered_fragments, parent_lp.clone(), mc, field_name, origin_lp,
variant_did);

View File

@ -58,7 +58,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> {
cmt: mc::cmt<'tcx>) -> RestrictionResult<'tcx> {
debug!("restrict(cmt={})", cmt.repr(self.bccx.tcx));
let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
let new_lp = |&: v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
match cmt.cat.clone() {
mc::cat_rvalue(..) => {

View File

@ -431,7 +431,7 @@ pub fn opt_loan_path<'tcx>(cmt: &mc::cmt<'tcx>) -> Option<Rc<LoanPath<'tcx>>> {
//! which allows it to share common loan path pieces as it
//! traverses the CMT.
let new_lp = |v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
let new_lp = |&: v: LoanPathKind<'tcx>| Rc::new(LoanPath::new(v, cmt.ty));
match cmt.cat {
mc::cat_rvalue(..) |

View File

@ -521,15 +521,17 @@ impl<'tcx> MoveData<'tcx> {
return true;
}
// FIXME(#19596) unbox `f`
fn each_extending_path(&self, index: MovePathIndex, f: |MovePathIndex| -> bool) -> bool {
if !f(index) {
// FIXME(#19596) This is a workaround, but there should be better way to do this
fn each_extending_path_<F>(&self, index: MovePathIndex, f: &mut F) -> bool where
F: FnMut(MovePathIndex) -> bool,
{
if !(*f)(index) {
return false;
}
let mut p = self.path_first_child(index);
while p != InvalidMovePathIndex {
if !self.each_extending_path(p, |x| f(x)) {
if !self.each_extending_path_(p, f) {
return false;
}
p = self.path_next_sibling(p);
@ -538,6 +540,12 @@ impl<'tcx> MoveData<'tcx> {
return true;
}
fn each_extending_path<F>(&self, index: MovePathIndex, mut f: F) -> bool where
F: FnMut(MovePathIndex) -> bool,
{
self.each_extending_path_(index, &mut f)
}
fn each_applicable_move<F>(&self, index0: MovePathIndex, mut f: F) -> bool where
F: FnMut(MoveIndex) -> bool,
{

View File

@ -278,7 +278,7 @@ Available lint options:
let max_name_len = plugin.iter().chain(builtin.iter())
.map(|&s| s.name.width(true))
.max().unwrap_or(0);
let padded = |x: &str| {
let padded = |&: x: &str| {
let mut s = repeat(" ").take(max_name_len - x.chars().count())
.collect::<String>();
s.push_str(x);
@ -289,7 +289,7 @@ Available lint options:
println!(" {} {:7.7} {}", padded("name"), "default", "meaning");
println!(" {} {:7.7} {}", padded("----"), "-------", "-------");
let print_lints = |lints: Vec<&Lint>| {
let print_lints = |&: lints: Vec<&Lint>| {
for lint in lints.into_iter() {
let name = lint.name_lower().replace("_", "-");
println!(" {} {:7.7} {}",
@ -305,7 +305,7 @@ Available lint options:
let max_name_len = plugin_groups.iter().chain(builtin_groups.iter())
.map(|&(s, _)| s.width(true))
.max().unwrap_or(0);
let padded = |x: &str| {
let padded = |&: x: &str| {
let mut s = repeat(" ").take(max_name_len - x.chars().count())
.collect::<String>();
s.push_str(x);
@ -316,7 +316,7 @@ Available lint options:
println!(" {} {}", padded("name"), "sub-lints");
println!(" {} {}", padded("----"), "---------");
let print_lint_groups = |lints: Vec<(&'static str, Vec<lint::LintId>)>| {
let print_lint_groups = |&: lints: Vec<(&'static str, Vec<lint::LintId>)>| {
for (name, to) in lints.into_iter() {
let name = name.chars().map(|x| x.to_lowercase())
.collect::<String>().replace("_", "-");

View File

@ -301,7 +301,7 @@ fn gather_flowgraph_variants(sess: &Session) -> Vec<borrowck_dot::Variant> {
let print_moves = config::FLOWGRAPH_PRINT_MOVES;
let print_assigns = config::FLOWGRAPH_PRINT_ASSIGNS;
let print_all = config::FLOWGRAPH_PRINT_ALL;
let opt = |print_which| sess.debugging_opt(print_which);
let opt = |&: print_which| sess.debugging_opt(print_which);
let mut variants = Vec::new();
if opt(print_all) || opt(print_loans) {
variants.push(borrowck_dot::Loans);
@ -365,7 +365,7 @@ impl UserIdentifiedItem {
}
fn to_one_node_id(self, user_option: &str, sess: &Session, map: &ast_map::Map) -> ast::NodeId {
let fail_because = |is_wrong_because| -> ast::NodeId {
let fail_because = |&: is_wrong_because| -> ast::NodeId {
let message =
format!("{} needs NodeId (int) or unique \
path suffix (b::c::d); got {}, which {}",

View File

@ -1448,7 +1448,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
let mut import_resolutions = module_.import_resolutions.borrow_mut();
let import_resolution = &mut (*import_resolutions)[target];
{
let check_and_write_import = |namespace, result: &_, used_public: &mut bool| {
let mut check_and_write_import = |&mut: namespace, result: &_, used_public: &mut bool| {
let namespace_name = match namespace {
TypeNS => "type",
ValueNS => "value",
@ -1691,7 +1691,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
// Merge the child item into the import resolution.
{
let merge_child_item = |namespace| {
let mut merge_child_item = |&mut : namespace| {
if name_bindings.defined_in_namespace_with(namespace, IMPORTABLE | PUBLIC) {
let namespace_name = match namespace {
TypeNS => "type",

View File

@ -127,7 +127,7 @@ pub const RLIB_BYTECODE_OBJECT_V1_DATA_OFFSET: uint =
pub fn find_crate_name(sess: Option<&Session>,
attrs: &[ast::Attribute],
input: &Input) -> String {
let validate = |s: String, span: Option<Span>| {
let validate = |&: s: String, span: Option<Span>| {
creader::validate_crate_name(sess, s[], span);
s
};

View File

@ -431,7 +431,7 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
// If we're verifying or linting, add them to the function pass
// manager.
let addpass = |pass: &str| {
let addpass = |&: pass: &str| {
pass.with_c_str(|s| llvm::LLVMRustAddPass(fpm, s))
};
if !config.no_verify { assert!(addpass("verify")); }
@ -652,7 +652,7 @@ pub fn run_passes(sess: &Session,
// Produce final compile outputs.
let copy_if_one_unit = |ext: &str, output_type: config::OutputType, keep_numbered: bool| {
let copy_if_one_unit = |&: ext: &str, output_type: config::OutputType, keep_numbered: bool| {
// Three cases:
if sess.opts.cg.codegen_units == 1 {
// 1) Only one codegen unit. In this case it's no difficulty
@ -677,7 +677,7 @@ pub fn run_passes(sess: &Session,
}
};
let link_obj = |output_path: &Path| {
let link_obj = |&: output_path: &Path| {
// Running `ld -r` on a single input is kind of pointless.
if sess.opts.cg.codegen_units == 1 {
fs::copy(&crate_output.with_extension("0.o"),
@ -993,7 +993,7 @@ unsafe fn configure_llvm(sess: &Session) {
let mut llvm_c_strs = Vec::new();
let mut llvm_args = Vec::new();
{
let add = |arg: &str| {
let mut add = |&mut : arg: &str| {
let s = arg.to_c_str();
llvm_args.push(s.as_ptr());
llvm_c_strs.push(s);

View File

@ -410,15 +410,15 @@ fn expand_nested_bindings<'a, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
}).collect()
}
type EnterPatterns<'a, 'p> = |&[&'p ast::Pat]|: 'a -> Option<Vec<&'p ast::Pat>>;
fn enter_match<'a, 'b, 'p, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
dm: &DefMap,
m: &[Match<'a, 'p, 'blk, 'tcx>],
col: uint,
val: ValueRef,
e: EnterPatterns<'b, 'p>)
-> Vec<Match<'a, 'p, 'blk, 'tcx>> {
fn enter_match<'a, 'b, 'p, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
dm: &DefMap,
m: &[Match<'a, 'p, 'blk, 'tcx>],
col: uint,
val: ValueRef,
mut e: F)
-> Vec<Match<'a, 'p, 'blk, 'tcx>> where
F: FnMut(&[&'p ast::Pat]) -> Option<Vec<&'p ast::Pat>>,
{
debug!("enter_match(bcx={}, m={}, col={}, val={})",
bcx.to_str(),
m.repr(bcx.tcx()),
@ -748,7 +748,7 @@ fn pick_column_to_specialize(def_map: &DefMap, m: &[Match]) -> Option<uint> {
}
}
let column_score: |&[Match], uint| -> uint = |m, col| {
let column_score = |&: m: &[Match], col: uint| -> uint {
let total_score = m.iter()
.map(|row| row.pats[col])
.map(|pat| pat_score(def_map, pat))

View File

@ -554,7 +554,7 @@ pub fn compare_scalar_types<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
t: Ty<'tcx>,
op: ast::BinOp)
-> Result<'blk, 'tcx> {
let f = |a| Result::new(cx, compare_scalar_values(cx, lhs, rhs, a, op));
let f = |&: a| Result::new(cx, compare_scalar_values(cx, lhs, rhs, a, op));
match t.sty {
ty::ty_tup(ref tys) if tys.is_empty() => f(nil_type),
@ -2749,7 +2749,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
let val = match item {
ast_map::NodeItem(i) => {
let ty = ty::node_id_to_type(ccx.tcx(), i.id);
let sym = || exported_name(ccx, id, ty, i.attrs[]);
let sym = |&:| exported_name(ccx, id, ty, i.attrs[]);
let v = match i.node {
ast::ItemStatic(_, _, ref expr) => {
@ -3013,14 +3013,14 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<String>) {
unsafe {
let mut declared = HashSet::new();
let iter_globals = |llmod| {
let iter_globals = |&: llmod| {
ValueIter {
cur: llvm::LLVMGetFirstGlobal(llmod),
step: llvm::LLVMGetNextGlobal,
}
};
let iter_functions = |llmod| {
let iter_functions = |&: llmod| {
ValueIter {
cur: llvm::LLVMGetFirstFunction(llmod),
step: llvm::LLVMGetNextFunction,

View File

@ -305,7 +305,7 @@ pub fn const_expr<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, e: &ast::Expr)
// the bool returned is whether this expression can be inlined into other crates
// if it's assigned to a static.
fn const_expr_unadjusted(cx: &CrateContext, e: &ast::Expr) -> ValueRef {
let map_list = |exprs: &[P<ast::Expr>]| {
let map_list = |&: exprs: &[P<ast::Expr>]| {
exprs.iter().map(|e| const_expr(cx, &**e).0)
.fold(Vec::new(), |mut l, val| { l.push(val); l })
};

View File

@ -2489,7 +2489,7 @@ fn prepare_enum_metadata<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
})
.collect();
let discriminant_type_metadata = |inttype| {
let discriminant_type_metadata = |&: inttype| {
// We can reuse the type of the discriminant for all monomorphized
// instances of an enum because it doesn't depend on any type parameters.
// The def_id, uniquely identifying the enum's polytype acts as key in

View File

@ -299,12 +299,16 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
// into a type to be destructed. If we want to end up with a Box pointer,
// then mk_ty should make a Box pointer (T -> Box<T>), if we want a
// borrowed reference then it should be T -> &T.
// FIXME(#19596) unbox `mk_ty`
fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
kind: &ty::UnsizeKind<'tcx>,
id: ast::NodeId,
unadjusted_ty: Ty<'tcx>,
mk_ty: |Ty<'tcx>| -> Ty<'tcx>) -> ValueRef {
fn unsized_info<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
kind: &ty::UnsizeKind<'tcx>,
id: ast::NodeId,
unadjusted_ty: Ty<'tcx>,
mk_ty: F) -> ValueRef where
F: FnOnce(Ty<'tcx>) -> Ty<'tcx>,
{
// FIXME(#19596) workaround: `|t| t` causes monomorphization recursion
fn identity<T>(t: T) -> T { t }
debug!("unsized_info(kind={}, id={}, unadjusted_ty={})",
kind, id, unadjusted_ty.repr(bcx.tcx()));
match kind {
@ -314,7 +318,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let ty_substs = substs.types.get_slice(subst::TypeSpace);
// The dtor for a field treats it like a value, so mk_ty
// should just be the identity function.
unsized_info(bcx, k, id, ty_substs[tp_index], |t| t)
unsized_info(bcx, k, id, ty_substs[tp_index], identity)
}
_ => bcx.sess().bug(format!("UnsizeStruct with bad sty: {}",
bcx.ty_to_string(unadjusted_ty))[])

View File

@ -615,7 +615,7 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// Array for the arguments we will pass to the rust function.
let mut llrust_args = Vec::new();
let mut next_foreign_arg_counter: c_uint = 0;
let next_foreign_arg: |pad: bool| -> c_uint = |pad: bool| {
let mut next_foreign_arg = |&mut : pad: bool| -> c_uint {
next_foreign_arg_counter += if pad {
2
} else {

View File

@ -181,7 +181,7 @@ pub fn trans_intrinsic_call<'a, 'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>,
// This should be caught by the intrinsicck pass
assert_eq!(in_type_size, out_type_size);
let nonpointer_nonaggregate = |llkind: TypeKind| -> bool {
let nonpointer_nonaggregate = |&: llkind: TypeKind| -> bool {
use llvm::TypeKind::*;
match llkind {
Half | Float | Double | X86_FP80 | FP128 |

View File

@ -139,7 +139,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
// This shouldn't need to option dance.
let mut hash_id = Some(hash_id);
let mk_lldecl = |abi: abi::Abi| {
let mut mk_lldecl = |&mut : abi: abi::Abi| {
let lldecl = if abi != abi::Rust {
foreign::decl_rust_fn_with_foreign_abi(ccx, mono_ty, s[])
} else {
@ -149,7 +149,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
ccx.monomorphized().borrow_mut().insert(hash_id.take().unwrap(), lldecl);
lldecl
};
let setup_lldecl = |lldecl, attrs: &[ast::Attribute]| {
let setup_lldecl = |&: lldecl, attrs: &[ast::Attribute]| {
base::update_linkage(ccx, lldecl, None, base::OriginalTranslation);
set_llvm_fn_attrs(ccx, attrs, lldecl);

View File

@ -223,7 +223,7 @@ fn check_object_safety_inner<'tcx>(tcx: &ty::ctxt<'tcx>,
}
// reason (a) above
let check_for_self_ty = |ty| {
let check_for_self_ty = |&: ty| {
if contains_illegal_self_type_reference(tcx, object_trait.def_id(), ty) {
Some(format!(
"cannot call a method (`{}`) whose type contains \

View File

@ -593,7 +593,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
// parameter (by inspecting parent of its binding declaration
// to see if it is introduced by a type or by a fn/impl).
let check_result = |this:&ConstraintContext| -> bool {
let check_result = |&: this:&ConstraintContext| -> bool {
let tcx = this.terms_cx.tcx;
let decl_id = this.find_binding_for_lifetime(param_id);
// Currently only called on lifetimes; double-checking that.

View File

@ -2016,7 +2016,7 @@ impl Clean<Vec<Item>> for ast::ViewItem {
None => false,
}
});
let convert = |node: &ast::ViewItem_| {
let convert = |&: node: &ast::ViewItem_| {
Item {
name: None,
attrs: self.attrs.clean(cx),

View File

@ -61,7 +61,7 @@ fn doit(sess: &parse::ParseSess, mut lexer: lexer::StringReader,
loop {
let next = lexer.next_token();
let snip = |sp| sess.span_diagnostic.cm.span_to_snippet(sp).unwrap();
let snip = |&: sp| sess.span_diagnostic.cm.span_to_snippet(sp).unwrap();
if next.tok == token::Eof { break }

View File

@ -344,7 +344,7 @@ mod test {
let (tx2, rx2) = channel();
spawn(move|| {
let send_as = |ip, val: &[u8]| {
let send_as = |&: ip, val: &[u8]| {
match UdpSocket::bind(ip) {
Ok(client) => {
let client = box client;

View File

@ -334,7 +334,7 @@ pub fn set_stderr(stderr: Box<Writer + Send>) -> Option<Box<Writer + Send>> {
// // io1 aliases io2
// })
// })
fn with_task_stdout(f: |&mut Writer| -> IoResult<()>) {
fn with_task_stdout<F>(f: F) where F: FnOnce(&mut Writer) -> IoResult<()> {
let mut my_stdout = LOCAL_STDOUT.with(|slot| {
slot.borrow_mut().take()
}).unwrap_or_else(|| {

View File

@ -321,10 +321,10 @@ pub fn float_to_str_bytes_common<T: Float>(
// cut off the one extra digit, and depending on its value
// round the remaining ones.
if limit_digits && dig == digit_count {
let ascii2value = |chr: u8| {
let ascii2value = |&: chr: u8| {
(chr as char).to_digit(radix).unwrap()
};
let value2ascii = |val: uint| {
let value2ascii = |&: val: uint| {
char::from_digit(val, radix).unwrap() as u8
};

View File

@ -174,7 +174,7 @@ impl Task {
///
/// It is invalid to call this function with a thread that has been previously
/// destroyed via a failed call to `run`.
pub fn run(mut self: Box<Task>, f: ||) -> Box<Task> {
pub fn run<F>(mut self: Box<Task>, f: F) -> Box<Task> where F: FnOnce() {
assert!(!self.is_destroyed(), "cannot re-use a destroyed thread");
// First, make sure that no one else is in TLS. This does not allow

View File

@ -26,13 +26,13 @@ struct ThreadInfo {
thread_local! { static THREAD_INFO: RefCell<Option<ThreadInfo>> = RefCell::new(None) }
impl ThreadInfo {
fn with<R>(f: |&mut ThreadInfo| -> R) -> R {
fn with<R, F>(f: F) -> R where F: FnOnce(&mut ThreadInfo) -> R {
if THREAD_INFO.destroyed() {
panic!("Use of std::thread::Thread::current() is not possible after \
the thread's local data has been destroyed");
}
THREAD_INFO.with(|c| {
THREAD_INFO.with(move |c| {
if c.borrow().is_none() {
*c.borrow_mut() = Some(ThreadInfo {
stack_bounds: (0, 0),

View File

@ -195,7 +195,7 @@ impl Process {
// up /dev/null into that file descriptor. Otherwise, the first file
// descriptor opened up in the child would be numbered as one of the
// stdio file descriptors, which is likely to wreak havoc.
let setup = |src: Option<P>, dst: c_int| {
let setup = |&: src: Option<P>, dst: c_int| {
let src = match src {
None => {
let flags = if dst == libc::STDIN_FILENO {

View File

@ -124,7 +124,9 @@ pub unsafe fn pipe() -> IoResult<(FileDesc, FileDesc)> {
}
}
pub fn fill_utf16_buf_and_decode(f: |*mut u16, DWORD| -> DWORD) -> Option<String> {
pub fn fill_utf16_buf_and_decode<F>(mut f: F) -> Option<String> where
F: FnMut(*mut u16, DWORD) -> DWORD,
{
unsafe {
let mut n = TMPBUF_SZ as DWORD;
let mut res = None;

View File

@ -162,7 +162,7 @@ impl Process {
// Similarly to unix, we don't actually leave holes for the stdio file
// descriptors, but rather open up /dev/null equivalents. These
// equivalents are drawn from libuv's windows process spawning.
let set_fd = |fd: &Option<P>, slot: &mut HANDLE,
let set_fd = |&: fd: &Option<P>, slot: &mut HANDLE,
is_stdin: bool| {
match *fd {
None => {

View File

@ -618,34 +618,38 @@ pub fn compute_id_range_for_fn_body(fk: visit::FnKind,
id_visitor.operation.result
}
// FIXME(#19596) unbox `it`
pub fn walk_pat(pat: &Pat, it: |&Pat| -> bool) -> bool {
if !it(pat) {
return false;
pub fn walk_pat<F>(pat: &Pat, mut it: F) -> bool where F: FnMut(&Pat) -> bool {
// FIXME(#19596) this is a workaround, but there should be a better way
fn walk_pat_<G>(pat: &Pat, it: &mut G) -> bool where G: FnMut(&Pat) -> bool {
if !(*it)(pat) {
return false;
}
match pat.node {
PatIdent(_, _, Some(ref p)) => walk_pat_(&**p, it),
PatStruct(_, ref fields, _) => {
fields.iter().all(|field| walk_pat_(&*field.node.pat, it))
}
PatEnum(_, Some(ref s)) | PatTup(ref s) => {
s.iter().all(|p| walk_pat_(&**p, it))
}
PatBox(ref s) | PatRegion(ref s) => {
walk_pat_(&**s, it)
}
PatVec(ref before, ref slice, ref after) => {
before.iter().all(|p| walk_pat_(&**p, it)) &&
slice.iter().all(|p| walk_pat_(&**p, it)) &&
after.iter().all(|p| walk_pat_(&**p, it))
}
PatMac(_) => panic!("attempted to analyze unexpanded pattern"),
PatWild(_) | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
PatEnum(_, _) => {
true
}
}
}
match pat.node {
PatIdent(_, _, Some(ref p)) => walk_pat(&**p, it),
PatStruct(_, ref fields, _) => {
fields.iter().all(|field| walk_pat(&*field.node.pat, |p| it(p)))
}
PatEnum(_, Some(ref s)) | PatTup(ref s) => {
s.iter().all(|p| walk_pat(&**p, |p| it(p)))
}
PatBox(ref s) | PatRegion(ref s) => {
walk_pat(&**s, it)
}
PatVec(ref before, ref slice, ref after) => {
before.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
slice.iter().all(|p| walk_pat(&**p, |p| it(p))) &&
after.iter().all(|p| walk_pat(&**p, |p| it(p)))
}
PatMac(_) => panic!("attempted to analyze unexpanded pattern"),
PatWild(_) | PatLit(_) | PatRange(_, _) | PatIdent(_, _, _) |
PatEnum(_, _) => {
true
}
}
walk_pat_(pat, &mut it)
}
pub trait EachViewItem {

View File

@ -47,18 +47,18 @@ pub trait ItemDecorator {
sp: Span,
meta_item: &ast::MetaItem,
item: &ast::Item,
push: |P<ast::Item>|);
push: Box<FnMut(P<ast::Item>)>);
}
impl<F> ItemDecorator for F
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, |P<ast::Item>|)
where F : Fn(&mut ExtCtxt, Span, &ast::MetaItem, &ast::Item, Box<FnMut(P<ast::Item>)>)
{
fn expand(&self,
ecx: &mut ExtCtxt,
sp: Span,
meta_item: &ast::MetaItem,
item: &ast::Item,
push: |P<ast::Item>|) {
push: Box<FnMut(P<ast::Item>)>) {
(*self)(ecx, sp, meta_item, item, push)
}
}

View File

@ -55,7 +55,7 @@ fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructur
cx.ident_of("Default"),
cx.ident_of("default")
);
let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
let default_call = |&: span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
return match *substr.fields {
StaticStruct(_, ref summary) => {

View File

@ -935,7 +935,7 @@ impl<'a> MethodDef<'a> {
// where each tuple has length = self_args.len()
let mut match_arms: Vec<ast::Arm> = variants.iter().enumerate()
.map(|(index, variant)| {
let mk_self_pat = |cx: &mut ExtCtxt, self_arg_name: &str| {
let mk_self_pat = |&: cx: &mut ExtCtxt, self_arg_name: &str| {
let (p, idents) = trait_.create_enum_variant_pattern(cx, type_ident,
&**variant,
self_arg_name,

View File

@ -71,7 +71,7 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
_ => cx.span_bug(trait_span, "incorrect number of arguments in `deriving(Hash)`")
};
let hash_ident = substr.method_ident;
let call_hash = |span, thing_expr| {
let call_hash = |&: span, thing_expr| {
let expr = cx.expr_method_call(span, thing_expr, hash_ident, vec!(state_expr.clone()));
cx.stmt_expr(expr)
};

View File

@ -45,7 +45,7 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
_span: Span,
mitem: &MetaItem,
item: &Item,
push: |P<Item>|) {
mut push: Box<FnMut(P<Item>)>) {
match mitem.node {
MetaNameValue(_, ref l) => {
cx.span_err(l.span, "unexpected value in `deriving`");
@ -64,7 +64,7 @@ pub fn expand_meta_deriving(cx: &mut ExtCtxt,
MetaWord(ref tname) => {
macro_rules! expand(($func:path) => ($func(cx, titem.span,
&**titem, item,
|i| push(i))));
|i| push.call_mut((i,)))));
match tname.get() {
"Clone" => expand!(clone::expand_deriving_clone),

View File

@ -71,7 +71,7 @@ fn zero_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
cx.ident_of("Zero"),
cx.ident_of("zero")
);
let zero_call = |span| cx.expr_call_global(span, zero_ident.clone(), Vec::new());
let zero_call = |&: span| cx.expr_call_global(span, zero_ident.clone(), Vec::new());
return match *substr.fields {
StaticStruct(_, ref summary) => {

View File

@ -424,7 +424,7 @@ pub fn expand_item(it: P<ast::Item>, fld: &mut MacroExpander)
// but that double-mut-borrows fld
let mut items: SmallVector<P<ast::Item>> = SmallVector::zero();
dec.expand(fld.cx, attr.span, &*attr.node.value, &*it,
|item| items.push(item));
box |&mut : item| items.push(item));
decorator_items.extend(items.into_iter()
.flat_map(|item| expand_item(item, fld).into_iter()));
@ -1660,7 +1660,7 @@ mod test {
assert!((shouldmatch.len() == 0) ||
(varrefs.len() > *shouldmatch.iter().max().unwrap()));
for (idx,varref) in varrefs.iter().enumerate() {
let print_hygiene_debug_info = || {
let print_hygiene_debug_info = |&:| {
// good lord, you can't make a path with 0 segments, can you?
let final_varref_ident = match varref.segments.last() {
Some(pathsegment) => pathsegment.identifier,

View File

@ -800,11 +800,11 @@ fn expand_parse_call(cx: &ExtCtxt,
tts: &[ast::TokenTree]) -> P<ast::Expr> {
let (cx_expr, tts_expr) = expand_tts(cx, sp, tts);
let cfg_call = || cx.expr_method_call(
let cfg_call = |&:| cx.expr_method_call(
sp, cx.expr_ident(sp, id_ext("ext_cx")),
id_ext("cfg"), Vec::new());
let parse_sess_call = || cx.expr_method_call(
let parse_sess_call = |&:| cx.expr_method_call(
sp, cx.expr_ident(sp, id_ext("ext_cx")),
id_ext("parse_sess"), Vec::new());

View File

@ -240,7 +240,7 @@ pub fn new_parser_from_tts<'a>(sess: &'a ParseSess,
/// add the path to the session's codemap and return the new filemap.
pub fn file_to_filemap(sess: &ParseSess, path: &Path, spanopt: Option<Span>)
-> Rc<FileMap> {
let err = |msg: &str| {
let err = |&: msg: &str| {
match spanopt {
Some(sp) => sess.span_diagnostic.span_fatal(sp, msg),
None => sess.span_diagnostic.handler().fatal(msg),
@ -399,7 +399,7 @@ pub fn char_lit(lit: &str) -> (char, int) {
.map(|x| (x, len as int))
}
let unicode_escape: || -> Option<(char, int)> = ||
let unicode_escape = |&: | -> Option<(char, int)>
if lit.as_bytes()[2] == b'{' {
let idx = lit.find('}').expect(msg2);
let subslice = lit[3..idx];
@ -426,7 +426,7 @@ pub fn str_lit(lit: &str) -> String {
let mut res = String::with_capacity(lit.len());
// FIXME #8372: This could be a for-loop if it didn't borrow the iterator
let error = |i| format!("lexer should have rejected {} at {}", lit, i);
let error = |&: i| format!("lexer should have rejected {} at {}", lit, i);
/// Eat everything up to a non-whitespace
fn eat<'a>(it: &mut iter::Peekable<(uint, char), str::CharIndices<'a>>) {
@ -561,7 +561,7 @@ pub fn float_lit(s: &str, suffix: Option<&str>, sd: &SpanHandler, sp: Span) -> a
/// Parse a string representing a byte literal into its final form. Similar to `char_lit`
pub fn byte_lit(lit: &str) -> (u8, uint) {
let err = |i| format!("lexer accepted invalid byte literal {} step {}", lit, i);
let err = |&: i| format!("lexer accepted invalid byte literal {} step {}", lit, i);
if lit.len() == 1 {
(lit.as_bytes()[0], 1)
@ -595,7 +595,7 @@ pub fn binary_lit(lit: &str) -> Rc<Vec<u8>> {
let mut res = Vec::with_capacity(lit.len());
// FIXME #8372: This could be a for-loop if it didn't borrow the iterator
let error = |i| format!("lexer should have rejected {} at {}", lit, i);
let error = |&: i| format!("lexer should have rejected {} at {}", lit, i);
/// Eat everything up to a non-whitespace
fn eat<'a, I: Iterator<(uint, u8)>>(it: &mut iter::Peekable<(uint, u8), I>) {

View File

@ -545,11 +545,11 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
let test_id = ecx.ident_of("test");
// creates self::test::$name
let test_path = |name| {
let test_path = |&: name| {
ecx.path(span, vec![self_id, test_id, ecx.ident_of(name)])
};
// creates $name: $expr
let field = |name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
let field = |&: name, expr| ecx.field_imm(span, ecx.ident_of(name), expr);
debug!("encoding {}", ast_util::path_name_i(path[]));
@ -563,7 +563,7 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
vec![name_expr]);
let ignore_expr = ecx.expr_bool(span, test.ignore);
let should_fail_path = |name| {
let should_fail_path = |&: name| {
ecx.path(span, vec![self_id, test_id, ecx.ident_of("ShouldFail"), ecx.ident_of(name)])
};
let fail_expr = match test.should_fail {

View File

@ -596,7 +596,7 @@ impl<'a> fmt::Show for TmFmt<'a> {
}
fn parse_type(fmt: &mut fmt::Formatter, ch: char, tm: &Tm) -> fmt::Result {
let die = || {
let die = |&:| {
unreachable!()
};
match ch {

View File

@ -11,6 +11,7 @@
//! Functions for computing canonical and compatible decompositions for Unicode characters.
use core::cmp::Ordering::{Equal, Less, Greater};
use core::ops::FnMut;
use core::option::Option;
use core::option::Option::{Some, None};
use core::slice::SliceExt;
@ -32,14 +33,15 @@ fn bsearch_table<T>(c: char, r: &'static [(char, &'static [T])]) -> Option<&'sta
}
/// Compute canonical Unicode decomposition for character
pub fn decompose_canonical(c: char, i: |char|) { d(c, i, false); }
pub fn decompose_canonical<F>(c: char, mut i: F) where F: FnMut(char) { d(c, &mut i, false); }
/// Compute canonical or compatible Unicode decomposition for character
pub fn decompose_compatible(c: char, i: |char|) { d(c, i, true); }
pub fn decompose_compatible<F>(c: char, mut i: F) where F: FnMut(char) { d(c, &mut i, true); }
fn d(c: char, i: |char|, k: bool) {
// FIXME(#19596) This is a workaround, we should use `F` instead of `&mut F`
fn d<F>(c: char, i: &mut F, k: bool) where F: FnMut(char) {
// 7-bit ASCII never decomposes
if c <= '\x7f' { i(c); return; }
if c <= '\x7f' { (*i)(c); return; }
// Perform decomposition for Hangul
if (c as u32) >= S_BASE && (c as u32) < (S_BASE + S_COUNT) {
@ -51,7 +53,7 @@ fn d(c: char, i: |char|, k: bool) {
match bsearch_table(c, canonical_table) {
Some(canon) => {
for x in canon.iter() {
d(*x, |b| i(b), k);
d(*x, i, k);
}
return;
}
@ -59,13 +61,13 @@ fn d(c: char, i: |char|, k: bool) {
}
// Bottom out if we're not doing compat.
if !k { i(c); return; }
if !k { (*i)(c); return; }
// Then check the compatibility decompositions
match bsearch_table(c, compatibility_table) {
Some(compat) => {
for x in compat.iter() {
d(*x, |b| i(b), k);
d(*x, i, k);
}
return;
}
@ -73,7 +75,7 @@ fn d(c: char, i: |char|, k: bool) {
}
// Finally bottom out.
i(c);
(*i)(c);
}
pub fn compose(a: char, b: char) -> Option<char> {
@ -108,23 +110,24 @@ const T_COUNT: u32 = 28;
const N_COUNT: u32 = (V_COUNT * T_COUNT);
const S_COUNT: u32 = (L_COUNT * N_COUNT);
// FIXME(#19596) This is a workaround, we should use `F` instead of `&mut F`
// Decompose a precomposed Hangul syllable
#[inline(always)]
fn decompose_hangul(s: char, f: |char|) {
fn decompose_hangul<F>(s: char, f: &mut F) where F: FnMut(char) {
use core::mem::transmute;
let si = s as u32 - S_BASE;
let li = si / N_COUNT;
unsafe {
f(transmute(L_BASE + li));
(*f)(transmute(L_BASE + li));
let vi = (si % N_COUNT) / T_COUNT;
f(transmute(V_BASE + vi));
(*f)(transmute(V_BASE + vi));
let ti = si % T_COUNT;
if ti > 0 {
f(transmute(T_BASE + ti));
(*f)(transmute(T_BASE + ti));
}
}
}