mirror of
https://github.com/rust-lang/rust.git
synced 2025-04-16 05:56:56 +00:00
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:
commit
47b8479e73
@ -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 {
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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 };
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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(),
|
||||
|
@ -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);
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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())) {
|
||||
|
@ -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);
|
||||
|
@ -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(..) => {
|
||||
|
@ -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(..) |
|
||||
|
@ -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,
|
||||
{
|
||||
|
@ -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("_", "-");
|
||||
|
@ -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 {}",
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
};
|
||||
|
@ -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);
|
||||
|
@ -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))
|
||||
|
@ -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,
|
||||
|
@ -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 })
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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))[])
|
||||
|
@ -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 {
|
||||
|
@ -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 |
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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.
|
||||
|
@ -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),
|
||||
|
@ -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 }
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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(|| {
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -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
|
||||
|
@ -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),
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
@ -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 => {
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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),
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -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,
|
||||
|
@ -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());
|
||||
|
||||
|
@ -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>) {
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user