diff --git a/src/libextra/fun_treemap.rs b/src/libextra/fun_treemap.rs index eb8c27e9902b5..5906e809c9856 100644 --- a/src/libextra/fun_treemap.rs +++ b/src/libextra/fun_treemap.rs @@ -66,9 +66,9 @@ pub fn traverse(m: Treemap, f: &fn(&K, &V)) { // matches to me, so I changed it. but that may be a // de-optimization -- tjc Node(@ref k, @ref v, left, right) => { - traverse(left, f); + traverse(left, |k,v| f(k,v)); f(k, v); - traverse(right, f); + traverse(right, |k,v| f(k,v)); } } } diff --git a/src/libextra/rope.rs b/src/libextra/rope.rs index fed73256c002c..71393ff9fae20 100644 --- a/src/libextra/rope.rs +++ b/src/libextra/rope.rs @@ -1078,7 +1078,7 @@ pub mod node { pub fn loop_chars(node: @Node, it: &fn(c: char) -> bool) -> bool { return loop_leaves(node,|leaf| { - leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(it) + leaf.content.slice(leaf.byte_offset, leaf.byte_len).iter().all(|c| it(c)) }); } @@ -1101,7 +1101,7 @@ pub mod node { loop { match (*current) { Leaf(x) => return it(x), - Concat(ref x) => if loop_leaves(x.left, it) { //non tail call + Concat(ref x) => if loop_leaves(x.left, |l| it(l)) { //non tail call current = x.right; //tail call } else { return false; diff --git a/src/libextra/sort.rs b/src/libextra/sort.rs index 5377dfadbaa11..10dbe2326d762 100644 --- a/src/libextra/sort.rs +++ b/src/libextra/sort.rs @@ -42,7 +42,8 @@ pub fn merge_sort(v: &[T], le: Le) -> ~[T] { let mid = v_len / 2 + begin; let a = (begin, mid); let b = (mid, end); - return merge(le, merge_sort_(v, a, le), merge_sort_(v, b, le)); + return merge(|x,y| le(x,y), merge_sort_(v, a, |x,y| le(x,y)), + merge_sort_(v, b, |x,y| le(x,y))); } fn merge(le: Le, a: &[T], b: &[T]) -> ~[T] { @@ -83,10 +84,10 @@ fn qsort(arr: &mut [T], left: uint, right: uint, compare_func: Le) { if right > left { let pivot = (left + right) / 2u; - let new_pivot = part::(arr, left, right, pivot, compare_func); + let new_pivot = part::(arr, left, right, pivot, |x,y| compare_func(x,y)); if new_pivot != 0u { // Need to do this check before recursing due to overflow - qsort::(arr, left, new_pivot - 1u, compare_func); + qsort::(arr, left, new_pivot - 1u, |x,y| compare_func(x,y)); } qsort::(arr, new_pivot + 1u, right, compare_func); } @@ -1202,7 +1203,7 @@ mod big_tests { struct LVal<'self> { val: uint, - key: &'self fn(@uint), + key: &'self fn:Copy(@uint), } #[unsafe_destructor] diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index 3908b61381b78..9c6be901d980a 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -563,7 +563,9 @@ impl RWlock { (&self.order_lock).acquire(); do (&self.access_lock).access_waitqueue { (&self.order_lock).release(); - task::rekillable(blk) + do task::rekillable { + blk() + } } } } @@ -1182,12 +1184,12 @@ mod tests { Write => x.write(blk), Downgrade => do x.write_downgrade |mode| { - (&mode).write(blk); + do mode.write { blk() }; }, DowngradeRead => do x.write_downgrade |mode| { let mode = x.downgrade(mode); - (&mode).read(blk); + do mode.read { blk() }; }, } } @@ -1340,10 +1342,10 @@ mod tests { fn lock_cond(x: &RWlock, downgrade: bool, blk: &fn(c: &Condvar)) { if downgrade { do x.write_downgrade |mode| { - (&mode).write_cond(blk) + do mode.write_cond |c| { blk(c) } } } else { - x.write_cond(blk) + do x.write_cond |c| { blk(c) } } } let x = ~RWlock(); diff --git a/src/libextra/test.rs b/src/libextra/test.rs index 209b46809ce31..50ca96e6e21df 100644 --- a/src/libextra/test.rs +++ b/src/libextra/test.rs @@ -678,7 +678,7 @@ impl BenchHarness { // Initial bench run to get ballpark figure. let mut n = 1_u64; - self.bench_n(n, f); + self.bench_n(n, |x| f(x)); while n < 1_000_000_000 && self.ns_elapsed() < 1_000_000_000 { @@ -694,7 +694,7 @@ impl BenchHarness { n = u64::max(u64::min(n+n/2, 100*last), last+1); n = round_up(n); - self.bench_n(n, f); + self.bench_n(n, |x| f(x)); } } @@ -714,7 +714,7 @@ impl BenchHarness { magnitude * 2); let samples = do vec::from_fn(n_samples) |_| { - self.bench_n(n_iter as u64, f); + self.bench_n(n_iter as u64, |x| f(x)); self.ns_per_iter() as f64 }; diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index 4622b8c728484..d546b48f81751 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -511,14 +511,14 @@ impl TreeNode { fn each<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode>, f: &fn(&'r K, &'r V) -> bool) -> bool { - node.iter().advance(|x| each(&x.left, f) && f(&x.key, &x.value) && - each(&x.right, f)) + node.iter().advance(|x| each(&x.left, |k,v| f(k,v)) && f(&x.key, &x.value) && + each(&x.right, |k,v| f(k,v))) } fn each_reverse<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode>, f: &fn(&'r K, &'r V) -> bool) -> bool { - node.iter().advance(|x| each_reverse(&x.right, f) && f(&x.key, &x.value) && - each_reverse(&x.left, f)) + node.iter().advance(|x| each_reverse(&x.right, |k,v| f(k,v)) && f(&x.key, &x.value) && + each_reverse(&x.left, |k,v| f(k,v))) } fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, @@ -527,9 +527,9 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, match *node { Some(~TreeNode{key: ref key, value: ref mut value, left: ref mut left, right: ref mut right, _}) => { - if !mutate_values(left, f) { return false } + if !mutate_values(left, |k,v| f(k,v)) { return false } if !f(key, value) { return false } - if !mutate_values(right, f) { return false } + if !mutate_values(right, |k,v| f(k,v)) { return false } } None => return false } diff --git a/src/libextra/workcache.rs b/src/libextra/workcache.rs index 567f9eda2fbae..4d4f3c3a49b01 100644 --- a/src/libextra/workcache.rs +++ b/src/libextra/workcache.rs @@ -107,7 +107,7 @@ struct WorkKey { impl to_bytes::IterBytes for WorkKey { #[inline] fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.kind.iter_bytes(lsb0, f) && self.name.iter_bytes(lsb0, f) + self.kind.iter_bytes(lsb0, |b| f(b)) && self.name.iter_bytes(lsb0, |b| f(b)) } } diff --git a/src/librust/rust.rs b/src/librust/rust.rs index 68427745ff592..ba5e592b605c3 100644 --- a/src/librust/rust.rs +++ b/src/librust/rust.rs @@ -57,13 +57,13 @@ impl ValidUsage { } enum Action<'self> { - Call(&'self fn(args: &[~str]) -> ValidUsage), - CallMain(&'static str, &'self fn()), + Call(&'self fn:Copy(args: &[~str]) -> ValidUsage), + CallMain(&'static str, &'self fn:Copy()), } enum UsageSource<'self> { UsgStr(&'self str), - UsgCall(&'self fn()), + UsgCall(&'self fn:Copy()), } struct Command<'self> { diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index 6268932ba9958..abfb5f7d4d4bf 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -48,7 +48,7 @@ pub fn mk_filesearch(maybe_sysroot: &Option<@Path>, debug!("filesearch: searching additional lib search paths [%?]", self.addl_lib_search_paths.len()); // a little weird - self.addl_lib_search_paths.iter().advance(f); + self.addl_lib_search_paths.iter().advance(|path| f(path)); debug!("filesearch: searching target lib path"); if !f(&make_target_lib_path(self.sysroot, diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index 1ec5c983f6248..2278658107344 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -189,11 +189,11 @@ fn parse_trait_store(st: &mut PState) -> ty::TraitStore { fn parse_substs(st: &mut PState, conv: conv_did) -> ty::substs { let self_r = parse_opt(st, |st| parse_region(st) ); - let self_ty = parse_opt(st, |st| parse_ty(st, conv) ); + let self_ty = parse_opt(st, |st| parse_ty(st, |x,y| conv(x,y)) ); assert_eq!(next(st), '['); let mut params: ~[ty::t] = ~[]; - while peek(st) != ']' { params.push(parse_ty(st, conv)); } + while peek(st) != ']' { params.push(parse_ty(st, |x,y| conv(x,y))); } st.pos = st.pos + 1u; return ty::substs { @@ -270,8 +270,8 @@ fn parse_str(st: &mut PState, term: char) -> ~str { } fn parse_trait_ref(st: &mut PState, conv: conv_did) -> ty::TraitRef { - let def = parse_def(st, NominalType, conv); - let substs = parse_substs(st, conv); + let def = parse_def(st, NominalType, |x,y| conv(x,y)); + let substs = parse_substs(st, |x,y| conv(x,y)); ty::TraitRef {def_id: def, substs: substs} } @@ -301,18 +301,18 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { 'c' => return ty::mk_char(), 't' => { assert_eq!(next(st), '['); - let def = parse_def(st, NominalType, conv); - let substs = parse_substs(st, conv); + let def = parse_def(st, NominalType, |x,y| conv(x,y)); + let substs = parse_substs(st, |x,y| conv(x,y)); assert_eq!(next(st), ']'); return ty::mk_enum(st.tcx, def, substs); } 'x' => { assert_eq!(next(st), '['); - let def = parse_def(st, NominalType, conv); - let substs = parse_substs(st, conv); + let def = parse_def(st, NominalType, |x,y| conv(x,y)); + let substs = parse_substs(st, |x,y| conv(x,y)); let store = parse_trait_store(st); let mt = parse_mutability(st); - let bounds = parse_bounds(st, conv); + let bounds = parse_bounds(st, |x,y| conv(x,y)); assert_eq!(next(st), ']'); return ty::mk_trait(st.tcx, def, substs, store, mt, bounds.builtin_bounds); } @@ -346,7 +346,7 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { 'T' => { assert_eq!(next(st), '['); let mut params = ~[]; - while peek(st) != ']' { params.push(parse_ty(st, conv)); } + while peek(st) != ']' { params.push(parse_ty(st, |x,y| conv(x,y))); } st.pos = st.pos + 1u; return ty::mk_tup(st.tcx, params); } @@ -380,15 +380,15 @@ fn parse_ty(st: &mut PState, conv: conv_did) -> ty::t { } } '"' => { - let _ = parse_def(st, TypeWithId, conv); - let inner = parse_ty(st, conv); + let _ = parse_def(st, TypeWithId, |x,y| conv(x,y)); + let inner = parse_ty(st, |x,y| conv(x,y)); inner } 'B' => ty::mk_opaque_box(st.tcx), 'a' => { assert_eq!(next(st), '['); - let did = parse_def(st, NominalType, conv); - let substs = parse_substs(st, conv); + let did = parse_def(st, NominalType, |x,y| conv(x,y)); + let substs = parse_substs(st, |x,y| conv(x,y)); assert_eq!(next(st), ']'); return ty::mk_struct(st.tcx, did, substs); } @@ -473,8 +473,8 @@ fn parse_closure_ty(st: &mut PState, conv: conv_did) -> ty::ClosureTy { let purity = parse_purity(next(st)); let onceness = parse_onceness(next(st)); let region = parse_region(st); - let bounds = parse_bounds(st, conv); - let sig = parse_sig(st, conv); + let bounds = parse_bounds(st, |x,y| conv(x,y)); + let sig = parse_sig(st, |x,y| conv(x,y)); ty::ClosureTy { purity: purity, sigil: sigil, @@ -500,7 +500,7 @@ fn parse_sig(st: &mut PState, conv: conv_did) -> ty::FnSig { assert_eq!(next(st), '['); let mut inputs = ~[]; while peek(st) != ']' { - inputs.push(parse_ty(st, conv)); + inputs.push(parse_ty(st, |x,y| conv(x,y))); } st.pos += 1u; // eat the ']' let ret_ty = parse_ty(st, conv); @@ -544,8 +544,8 @@ pub fn parse_type_param_def_data(data: &[u8], start: uint, } fn parse_type_param_def(st: &mut PState, conv: conv_did) -> ty::TypeParameterDef { - ty::TypeParameterDef {def_id: parse_def(st, NominalType, conv), - bounds: @parse_bounds(st, conv)} + ty::TypeParameterDef {def_id: parse_def(st, NominalType, |x,y| conv(x,y)), + bounds: @parse_bounds(st, |x,y| conv(x,y))} } fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { @@ -571,7 +571,7 @@ fn parse_bounds(st: &mut PState, conv: conv_did) -> ty::ParamBounds { param_bounds.builtin_bounds.add(ty::BoundSized); } 'I' => { - param_bounds.trait_bounds.push(@parse_trait_ref(st, conv)); + param_bounds.trait_bounds.push(@parse_trait_ref(st, |x,y| conv(x,y))); } '.' => { return param_bounds; diff --git a/src/librustc/middle/borrowck/move_data.rs b/src/librustc/middle/borrowck/move_data.rs index 7396dc1bd7bff..623dbbd61b244 100644 --- a/src/librustc/middle/borrowck/move_data.rs +++ b/src/librustc/middle/borrowck/move_data.rs @@ -411,7 +411,7 @@ impl MoveData { let mut p = self.path(index).first_child; while p != InvalidMovePathIndex { - if !self.each_extending_path(p, f) { + if !self.each_extending_path(p, |x| f(x)) { return false; } p = self.path(p).next_sibling; diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index f0c091ac53cae..d4b91ed589d0f 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -171,7 +171,7 @@ fn with_appropriate_checker(cx: Context, id: node_id, // check that only immutable variables are implicitly copied in check_imm_free_var(cx, fv.def, fv.span); - check_freevar_bounds(cx, fv.span, var_t, bounds); + check_freevar_bounds(cx, fv.span, var_t, bounds, None); } fn check_for_box(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { @@ -182,13 +182,18 @@ fn with_appropriate_checker(cx: Context, id: node_id, // check that only immutable variables are implicitly copied in check_imm_free_var(cx, fv.def, fv.span); - check_freevar_bounds(cx, fv.span, var_t, bounds); + check_freevar_bounds(cx, fv.span, var_t, bounds, None); } - fn check_for_block(cx: Context, fv: &freevar_entry, bounds: ty::BuiltinBounds) { + fn check_for_block(cx: Context, fv: &freevar_entry, + bounds: ty::BuiltinBounds, region: ty::Region) { let id = ast_util::def_id_of_def(fv.def).node; let var_t = ty::node_id_to_type(cx.tcx, id); - check_freevar_bounds(cx, fv.span, var_t, bounds); + // FIXME(#3569): Figure out whether the implicit borrow is actually + // mutable. Currently we assume all upvars are referenced mutably. + let implicit_borrowed_type = ty::mk_mut_rptr(cx.tcx, region, var_t); + check_freevar_bounds(cx, fv.span, implicit_borrowed_type, + bounds, Some(var_t)); } fn check_for_bare(cx: Context, fv: @freevar_entry) { @@ -205,8 +210,9 @@ fn with_appropriate_checker(cx: Context, id: node_id, ty::ty_closure(ty::ClosureTy {sigil: ManagedSigil, bounds: bounds, _}) => { b(|cx, fv| check_for_box(cx, fv, bounds)) } - ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, bounds: bounds, _}) => { - b(|cx, fv| check_for_block(cx, fv, bounds)) + ty::ty_closure(ty::ClosureTy {sigil: BorrowedSigil, bounds: bounds, + region: region, _}) => { + b(|cx, fv| check_for_block(cx, fv, bounds, region)) } ty::ty_bare_fn(_) => { b(check_for_bare) @@ -366,14 +372,21 @@ pub fn check_typaram_bounds(cx: Context, } pub fn check_freevar_bounds(cx: Context, sp: span, ty: ty::t, - bounds: ty::BuiltinBounds) + bounds: ty::BuiltinBounds, referenced_ty: Option) { do check_builtin_bounds(cx, ty, bounds) |missing| { - cx.tcx.sess.span_err( - sp, - fmt!("cannot capture variable of type `%s`, which does not fulfill \ - `%s`, in a bounded closure", - ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx))); + // Will be Some if the freevar is implicitly borrowed (stack closure). + // Emit a less mysterious error message in this case. + match referenced_ty { + Some(rty) => cx.tcx.sess.span_err(sp, + fmt!("cannot implicitly borrow variable of type `%s` in a bounded \ + stack closure (implicit reference does not fulfill `%s`)", + ty_to_str(cx.tcx, rty), missing.user_string(cx.tcx))), + None => cx.tcx.sess.span_err(sp, + fmt!("cannot capture variable of type `%s`, which does \ + not fulfill `%s`, in a bounded closure", + ty_to_str(cx.tcx, ty), missing.user_string(cx.tcx))), + } cx.tcx.sess.span_note( sp, fmt!("this closure's environment must satisfy `%s`", diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 52c01fa76476b..a2907e9912092 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -890,7 +890,7 @@ impl mem_categorization_ctxt { pat, downcast_cmt, subpat_ty, InteriorField(PositionalField(i))); - self.cat_pattern(subcmt, subpat, op); + self.cat_pattern(subcmt, subpat, |x,y| op(x,y)); } } Some(&ast::def_fn(*)) | @@ -901,12 +901,12 @@ impl mem_categorization_ctxt { self.cat_imm_interior( pat, cmt, subpat_ty, InteriorField(PositionalField(i))); - self.cat_pattern(cmt_field, subpat, op); + self.cat_pattern(cmt_field, subpat, |x,y| op(x,y)); } } Some(&ast::def_static(*)) => { for subpats.iter().advance |&subpat| { - self.cat_pattern(cmt, subpat, op); + self.cat_pattern(cmt, subpat, |x,y| op(x,y)); } } _ => { @@ -930,7 +930,7 @@ impl mem_categorization_ctxt { for field_pats.iter().advance |fp| { let field_ty = self.pat_ty(fp.pat); // see (*) let cmt_field = self.cat_field(pat, cmt, fp.ident, field_ty); - self.cat_pattern(cmt_field, fp.pat, op); + self.cat_pattern(cmt_field, fp.pat, |x,y| op(x,y)); } } @@ -942,7 +942,7 @@ impl mem_categorization_ctxt { self.cat_imm_interior( pat, cmt, subpat_ty, InteriorField(PositionalField(i))); - self.cat_pattern(subcmt, subpat, op); + self.cat_pattern(subcmt, subpat, |x,y| op(x,y)); } } @@ -956,15 +956,15 @@ impl mem_categorization_ctxt { ast::pat_vec(ref before, slice, ref after) => { let elt_cmt = self.cat_index(pat, cmt, 0); for before.iter().advance |&before_pat| { - self.cat_pattern(elt_cmt, before_pat, op); + self.cat_pattern(elt_cmt, before_pat, |x,y| op(x,y)); } for slice.iter().advance |&slice_pat| { let slice_ty = self.pat_ty(slice_pat); let slice_cmt = self.cat_rvalue(pat, slice_ty); - self.cat_pattern(slice_cmt, slice_pat, op); + self.cat_pattern(slice_cmt, slice_pat, |x,y| op(x,y)); } for after.iter().advance |&after_pat| { - self.cat_pattern(elt_cmt, after_pat, op); + self.cat_pattern(elt_cmt, after_pat, |x,y| op(x,y)); } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index efa69ab5e625b..d9fea12134684 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -674,7 +674,7 @@ pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, int::to_str(variant.disr_val)); let variant_cx = iter_variant(variant_cx, repr, av, *variant, - substs.tps, f); + substs.tps, |x,y,z| f(x,y,z)); match adt::trans_case(cx, repr, variant.disr_val) { _match::single_result(r) => { AddCase(llswitch, r.val, variant_cx.llbb) diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 7624fb13903f5..b255f2ca78c7f 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -36,6 +36,8 @@ use core::cast; use core::hashmap::{HashMap}; use core::libc::{c_uint, c_longlong, c_ulonglong}; use core::to_bytes; +use core::str; +use core::vec::raw::to_ptr; use core::vec; use syntax::ast::ident; use syntax::ast_map::{path, path_elt}; @@ -860,7 +862,7 @@ pub fn is_null(val: ValueRef) -> bool { } // Used to identify cached monomorphized functions and vtables -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub enum mono_param_id { mono_precise(ty::t, Option<@~[mono_id]>), mono_any, @@ -870,7 +872,7 @@ pub enum mono_param_id { datum::DatumMode), } -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub enum MonoDataClass { MonoBits, // Anything not treated differently from arbitrary integer data MonoNonNull, // Non-null pointers (used for optional-pointer optimization) @@ -895,7 +897,7 @@ pub fn mono_data_classify(t: ty::t) -> MonoDataClass { } -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct mono_id_ { def: ast::def_id, params: ~[mono_param_id], @@ -904,40 +906,6 @@ pub struct mono_id_ { pub type mono_id = @mono_id_; -impl to_bytes::IterBytes for mono_param_id { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - mono_precise(t, ref mids) => { - 0u8.iter_bytes(lsb0, f) && - ty::type_id(t).iter_bytes(lsb0, f) && - mids.iter_bytes(lsb0, f) - } - - mono_any => 1u8.iter_bytes(lsb0, f), - - mono_repr(ref a, ref b, ref c, ref d) => { - 2u8.iter_bytes(lsb0, f) && - a.iter_bytes(lsb0, f) && - b.iter_bytes(lsb0, f) && - c.iter_bytes(lsb0, f) && - d.iter_bytes(lsb0, f) - } - } - } -} - -impl to_bytes::IterBytes for MonoDataClass { - fn iter_bytes(&self, lsb0: bool, f:to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for mono_id_ { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.def.iter_bytes(lsb0, f) && self.params.iter_bytes(lsb0, f) - } -} - pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { let cond = build::ICmp(cx, lib::llvm::IntULT, a, b); return build::Select(cx, cond, b, a); diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index f1172fb1da65f..b8ee1eee26e1c 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -52,7 +52,7 @@ use syntax; // Data types -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct field { ident: ast::ident, mt: mt @@ -96,13 +96,13 @@ impl Method { } } -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct mt { ty: t, mutbl: ast::mutability, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable, IterBytes)] pub enum vstore { vstore_fixed(uint), vstore_uniq, @@ -133,7 +133,7 @@ pub struct field_ty { // Contains information needed to resolve types and (in the future) look up // the types of AST nodes. -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct creader_cache_key { cnum: int, pos: uint, @@ -142,14 +142,6 @@ pub struct creader_cache_key { type creader_cache = @mut HashMap; -impl to_bytes::IterBytes for creader_cache_key { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.cnum.iter_bytes(lsb0, f) && - self.pos.iter_bytes(lsb0, f) && - self.len.iter_bytes(lsb0, f) - } -} - struct intern_key { sty: *sty, } @@ -168,6 +160,8 @@ impl cmp::Eq for intern_key { } } +// NB: Do not replace this with #[deriving(IterBytes)], as above. (Figured +// this out the hard way.) impl to_bytes::IterBytes for intern_key { fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { unsafe { @@ -372,14 +366,14 @@ pub fn type_has_regions(t: t) -> bool { } pub fn type_id(t: t) -> uint { get(t).id } -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct BareFnTy { purity: ast::purity, abis: AbiSet, sig: FnSig } -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct ClosureTy { purity: ast::purity, sigil: ast::Sigil, @@ -396,32 +390,13 @@ pub struct ClosureTy { * - `lifetimes` is the list of region names bound in this fn. * - `inputs` is the list of arguments and their modes. * - `output` is the return type. */ -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct FnSig { bound_lifetime_names: OptVec, inputs: ~[t], output: t } -impl to_bytes::IterBytes for BareFnTy { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.purity.iter_bytes(lsb0, f) && - self.abis.iter_bytes(lsb0, f) && - self.sig.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for ClosureTy { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.purity.iter_bytes(lsb0, f) && - self.sigil.iter_bytes(lsb0, f) && - self.onceness.iter_bytes(lsb0, f) && - self.region.iter_bytes(lsb0, f) && - self.sig.iter_bytes(lsb0, f) && - self.bounds.iter_bytes(lsb0, f) - } -} - #[deriving(Eq, IterBytes)] pub struct param_ty { idx: uint, @@ -526,7 +501,7 @@ type opt_region = Option; * - `self_ty` is the type to which `self` should be remapped, if any. The * `self` type is rather funny in that it can only appear on traits and is * always substituted away to the implementing type for a trait. */ -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct substs { self_r: opt_region, self_ty: Option, @@ -582,7 +557,7 @@ mod primitives { // NB: If you change this, you'll probably want to change the corresponding // AST structure in libsyntax/ast.rs as well. -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub enum sty { ty_nil, ty_bot, @@ -714,62 +689,33 @@ impl CLike for BuiltinBound { } } -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct TyVid(uint); -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct IntVid(uint); -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub struct FloatVid(uint); -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable, IterBytes)] pub struct RegionVid { id: uint } -#[deriving(Eq)] +#[deriving(Eq, IterBytes)] pub enum InferTy { TyVar(TyVid), IntVar(IntVid), FloatVar(FloatVid) } -impl to_bytes::IterBytes for InferTy { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - TyVar(ref tv) => { - 0u8.iter_bytes(lsb0, f) && tv.iter_bytes(lsb0, f) - } - IntVar(ref iv) => { - 1u8.iter_bytes(lsb0, f) && iv.iter_bytes(lsb0, f) - } - FloatVar(ref fv) => { - 2u8.iter_bytes(lsb0, f) && fv.iter_bytes(lsb0, f) - } - } - } -} - -#[deriving(Encodable, Decodable)] +#[deriving(Encodable, Decodable, IterBytes)] pub enum InferRegion { ReVar(RegionVid), ReSkolemized(uint, bound_region) } -impl to_bytes::IterBytes for InferRegion { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - ReVar(ref rv) => { - 0u8.iter_bytes(lsb0, f) && rv.iter_bytes(lsb0, f) - } - ReSkolemized(ref v, _) => { - 1u8.iter_bytes(lsb0, f) && v.iter_bytes(lsb0, f) - } - } - } -} - impl cmp::Eq for InferRegion { fn eq(&self, other: &InferRegion) -> bool { match ((*self), *other) { @@ -849,30 +795,6 @@ impl ToStr for IntVarValue { } } -impl to_bytes::IterBytes for TyVid { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.to_uint().iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for IntVid { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.to_uint().iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for FloatVid { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.to_uint().iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for RegionVid { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.to_uint().iter_bytes(lsb0, f) - } -} - pub struct TypeParameterDef { def_id: ast::def_id, bounds: @ParamBounds @@ -1319,15 +1241,15 @@ pub fn maybe_walk_ty(ty: t, f: &fn(t) -> bool) { } ty_enum(_, ref substs) | ty_struct(_, ref substs) | ty_trait(_, ref substs, _, _, _) => { - for (*substs).tps.iter().advance |subty| { maybe_walk_ty(*subty, f); } + for (*substs).tps.iter().advance |subty| { maybe_walk_ty(*subty, |x| f(x)); } } - ty_tup(ref ts) => { for ts.iter().advance |tt| { maybe_walk_ty(*tt, f); } } + ty_tup(ref ts) => { for ts.iter().advance |tt| { maybe_walk_ty(*tt, |x| f(x)); } } ty_bare_fn(ref ft) => { - for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, f); } + for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, |x| f(x)); } maybe_walk_ty(ft.sig.output, f); } ty_closure(ref ft) => { - for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, f); } + for ft.sig.inputs.iter().advance |a| { maybe_walk_ty(*a, |x| f(x)); } maybe_walk_ty(ft.sig.output, f); } } @@ -1409,7 +1331,7 @@ fn fold_sty(sty: &sty, fldop: &fn(t) -> t) -> sty { // Folds types from the bottom up. pub fn fold_ty(cx: ctxt, t0: t, fldop: &fn(t) -> t) -> t { - let sty = fold_sty(&get(t0).sty, |t| fold_ty(cx, fldop(t), fldop)); + let sty = fold_sty(&get(t0).sty, |t| fold_ty(cx, fldop(t), |t| fldop(t))); fldop(mk_t(cx, sty)) } @@ -1423,8 +1345,8 @@ pub fn walk_regions_and_ty( fold_regions_and_ty( cx, ty, |r| { walkr(r); r }, - |t| { walk_regions_and_ty(cx, t, walkr, walkt); t }, - |t| { walk_regions_and_ty(cx, t, walkr, walkt); t }); + |t| { walk_regions_and_ty(cx, t, |r| walkr(r), |t| walkt(t)); t }, + |t| { walk_regions_and_ty(cx, t, |r| walkr(r), |t| walkt(t)); t }); } } @@ -1504,8 +1426,8 @@ pub fn fold_regions( fold_regions_and_ty( cx, ty, |r| fldr(r, in_fn), - |t| do_fold(cx, t, true, fldr), - |t| do_fold(cx, t, in_fn, fldr)) + |t| do_fold(cx, t, true, |r,b| fldr(r,b)), + |t| do_fold(cx, t, in_fn, |r,b| fldr(r,b))) } do_fold(cx, ty, false, fldr) } @@ -1906,7 +1828,9 @@ impl TypeContents { // Currently all noncopyable existentials are 2nd-class types // behind owned pointers. With dynamically-sized types, remove // this assertion. - assert!(self.intersects(TC_OWNED_POINTER)); + assert!(self.intersects(TC_OWNED_POINTER) || + // (...or stack closures without a copy bound.) + self.intersects(TC_BORROWED_POINTER)); } let tc = TC_MANAGED + TC_DTOR + TypeContents::sendable(cx); self.intersects(tc) @@ -2272,7 +2196,14 @@ pub fn type_contents(cx: ctxt, ty: t) -> TypeContents { ast::Once => TC_ONCE_CLOSURE, ast::Many => TC_NONE }; - st + rt + ot + // Prevent noncopyable types captured in the environment from being copied. + let ct = if cty.bounds.contains_elem(BoundCopy) || + cty.sigil == ast::ManagedSigil { + TC_NONE + } else { + TC_NONCOPY_TRAIT + }; + st + rt + ot + ct } fn trait_contents(store: TraitStore, mutbl: ast::mutability, @@ -2452,7 +2383,7 @@ pub fn type_structurally_contains(cx: ctxt, for (*enum_variants(cx, did)).iter().advance |variant| { for variant.args.iter().advance |aty| { let sty = subst(cx, substs, *aty); - if type_structurally_contains(cx, sty, test) { return true; } + if type_structurally_contains(cx, sty, |x| test(x)) { return true; } } } return false; @@ -2461,14 +2392,14 @@ pub fn type_structurally_contains(cx: ctxt, let r = lookup_struct_fields(cx, did); for r.iter().advance |field| { let ft = lookup_field_type(cx, did, field.id, substs); - if type_structurally_contains(cx, ft, test) { return true; } + if type_structurally_contains(cx, ft, |x| test(x)) { return true; } } return false; } ty_tup(ref ts) => { for ts.iter().advance |tt| { - if type_structurally_contains(cx, *tt, test) { return true; } + if type_structurally_contains(cx, *tt, |x| test(x)) { return true; } } return false; } @@ -2744,123 +2675,6 @@ impl cmp::TotalEq for bound_region { } } -impl to_bytes::IterBytes for vstore { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - vstore_fixed(ref u) => { - 0u8.iter_bytes(lsb0, f) && u.iter_bytes(lsb0, f) - } - vstore_uniq => 1u8.iter_bytes(lsb0, f), - vstore_box => 2u8.iter_bytes(lsb0, f), - - vstore_slice(ref r) => { - 3u8.iter_bytes(lsb0, f) && r.iter_bytes(lsb0, f) - } - } - } -} - -impl to_bytes::IterBytes for substs { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.self_r.iter_bytes(lsb0, f) && - self.self_ty.iter_bytes(lsb0, f) && - self.tps.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for mt { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.ty.iter_bytes(lsb0, f) && self.mutbl.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for field { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.ident.iter_bytes(lsb0, f) && self.mt.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for FnSig { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.inputs.iter_bytes(lsb0, f) && self.output.iter_bytes(lsb0, f) - } -} - -impl to_bytes::IterBytes for sty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - ty_nil => 0u8.iter_bytes(lsb0, f), - ty_bool => 1u8.iter_bytes(lsb0, f), - - ty_int(ref t) => 2u8.iter_bytes(lsb0, f) && t.iter_bytes(lsb0, f), - - ty_uint(ref t) => 3u8.iter_bytes(lsb0, f) && t.iter_bytes(lsb0, f), - - ty_float(ref t) => 4u8.iter_bytes(lsb0, f) && t.iter_bytes(lsb0, f), - - ty_estr(ref v) => 5u8.iter_bytes(lsb0, f) && v.iter_bytes(lsb0, f), - - ty_enum(ref did, ref substs) => { - 6u8.iter_bytes(lsb0, f) && - did.iter_bytes(lsb0, f) && - substs.iter_bytes(lsb0, f) - } - - ty_box(ref mt) => 7u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - - ty_evec(ref mt, ref v) => { - 8u8.iter_bytes(lsb0, f) && - mt.iter_bytes(lsb0, f) && - v.iter_bytes(lsb0, f) - } - - ty_unboxed_vec(ref mt) => 9u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - - ty_tup(ref ts) => 10u8.iter_bytes(lsb0, f) && ts.iter_bytes(lsb0, f), - - ty_bare_fn(ref ft) => 12u8.iter_bytes(lsb0, f) && ft.iter_bytes(lsb0, f), - - ty_self(ref did) => 13u8.iter_bytes(lsb0, f) && did.iter_bytes(lsb0, f), - - ty_infer(ref v) => 14u8.iter_bytes(lsb0, f) && v.iter_bytes(lsb0, f), - - ty_param(ref p) => 15u8.iter_bytes(lsb0, f) && p.iter_bytes(lsb0, f), - - ty_type => 16u8.iter_bytes(lsb0, f), - ty_bot => 17u8.iter_bytes(lsb0, f), - - ty_ptr(ref mt) => 18u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - - ty_uniq(ref mt) => 19u8.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f), - - ty_trait(ref did, ref substs, ref v, ref mutbl, bounds) => { - 20u8.iter_bytes(lsb0, f) && - did.iter_bytes(lsb0, f) && - substs.iter_bytes(lsb0, f) && - v.iter_bytes(lsb0, f) && - mutbl.iter_bytes(lsb0, f) && - bounds.iter_bytes(lsb0, f) - } - - ty_opaque_closure_ptr(ref ck) => 21u8.iter_bytes(lsb0, f) && ck.iter_bytes(lsb0, f), - - ty_opaque_box => 22u8.iter_bytes(lsb0, f), - - ty_struct(ref did, ref substs) => { - 23u8.iter_bytes(lsb0, f) && did.iter_bytes(lsb0, f) && substs.iter_bytes(lsb0, f) - } - - ty_rptr(ref r, ref mt) => { - 24u8.iter_bytes(lsb0, f) && r.iter_bytes(lsb0, f) && mt.iter_bytes(lsb0, f) - } - - ty_err => 25u8.iter_bytes(lsb0, f), - - ty_closure(ref ct) => 26u8.iter_bytes(lsb0, f) && ct.iter_bytes(lsb0, f), - } - } -} - pub fn node_id_to_trait_ref(cx: ctxt, id: ast::node_id) -> @ty::TraitRef { match cx.trait_refs.find(&id) { Some(&t) => t, diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 160737142c8ca..fb79a7c3c994e 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -112,7 +112,7 @@ pub fn replace_bound_regions_in_fn_sig( // kinds of types. This had already caused me several // bugs so I decided to switch over. do ty::fold_regions(tcx, *ty) |r, in_fn| { - if !in_fn { isr = append_isr(isr, to_r, r); } + if !in_fn { isr = append_isr(isr, |br| to_r(br), r); } r }; @@ -211,18 +211,18 @@ pub fn relate_nested_regions( match ty::get(ty).sty { ty::ty_rptr(r, ref mt) | ty::ty_evec(ref mt, ty::vstore_slice(r)) => { - relate(*the_stack, r, relate_op); + relate(*the_stack, r, |x,y| relate_op(x,y)); the_stack.push(r); - walk_ty(tcx, the_stack, mt.ty, relate_op); + walk_ty(tcx, the_stack, mt.ty, |x,y| relate_op(x,y)); the_stack.pop(); } _ => { ty::fold_regions_and_ty( tcx, ty, - |r| { relate(*the_stack, r, relate_op); r }, - |t| { walk_ty(tcx, the_stack, t, relate_op); t }, - |t| { walk_ty(tcx, the_stack, t, relate_op); t }); + |r| { relate( *the_stack, r, |x,y| relate_op(x,y)); r }, + |t| { walk_ty(tcx, the_stack, t, |x,y| relate_op(x,y)); t }, + |t| { walk_ty(tcx, the_stack, t, |x,y| relate_op(x,y)); t }); } } } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 1bfe452f25e09..3e2d4a71dfbe9 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -582,7 +582,7 @@ impl InferCtxt { debug!("commit()"); do indent { - let r = self.try(f); + let r = self.try(|| f()); self.ty_var_bindings.bindings.truncate(0); self.int_var_bindings.bindings.truncate(0); @@ -836,6 +836,6 @@ pub fn fold_regions_in_sig( fldr: &fn(r: ty::Region, in_fn: bool) -> ty::Region) -> ty::FnSig { do ty::fold_sig(fn_sig) |t| { - ty::fold_regions(tcx, t, fldr) + ty::fold_regions(tcx, t, |r, in_fn| fldr(r, in_fn)) } } diff --git a/src/librustc/middle/typeck/infer/region_inference.rs b/src/librustc/middle/typeck/infer/region_inference.rs index 0aad161a6788f..4380711b78e88 100644 --- a/src/librustc/middle/typeck/infer/region_inference.rs +++ b/src/librustc/middle/typeck/infer/region_inference.rs @@ -548,43 +548,18 @@ use util::ppaux::note_and_explain_region; use core::cell::Cell; use core::hashmap::{HashMap, HashSet}; -use core::to_bytes; use core::uint; use core::vec; use syntax::codemap::span; use syntax::ast; -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] enum Constraint { ConstrainVarSubVar(RegionVid, RegionVid), ConstrainRegSubVar(Region, RegionVid), ConstrainVarSubReg(RegionVid, Region) } -impl to_bytes::IterBytes for Constraint { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - ConstrainVarSubVar(ref v0, ref v1) => { - 0u8.iter_bytes(lsb0, f) && - v0.iter_bytes(lsb0, f) && - v1.iter_bytes(lsb0, f) - } - - ConstrainRegSubVar(ref ra, ref va) => { - 1u8.iter_bytes(lsb0, f) && - ra.iter_bytes(lsb0, f) && - va.iter_bytes(lsb0, f) - } - - ConstrainVarSubReg(ref va, ref ra) => { - 2u8.iter_bytes(lsb0, f) && - va.iter_bytes(lsb0, f) && - ra.iter_bytes(lsb0, f) - } - } - } -} - #[deriving(Eq, IterBytes)] struct TwoRegions { a: Region, diff --git a/src/libstd/hashmap.rs b/src/libstd/hashmap.rs index bfa0f2fa124d2..7f9fb6ad9380f 100644 --- a/src/libstd/hashmap.rs +++ b/src/libstd/hashmap.rs @@ -671,7 +671,7 @@ impl Set for HashSet { fn symmetric_difference(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.difference(other, f) && other.difference(self, f) + self.difference(other, |t| f(t)) && other.difference(self, |t| f(t)) } /// Visit the values representing the intersection @@ -681,7 +681,8 @@ impl Set for HashSet { /// Visit the values representing the union fn union(&self, other: &HashSet, f: &fn(&T) -> bool) -> bool { - self.iter().advance(f) && other.iter().advance(|v| self.contains(v) || f(v)) + self.iter().advance(|t| f(t)) && + other.iter().advance(|v| self.contains(v) || f(v)) } } diff --git a/src/libstd/iterator.rs b/src/libstd/iterator.rs index 765bf3b36f285..976ca8bae7a87 100644 --- a/src/libstd/iterator.rs +++ b/src/libstd/iterator.rs @@ -964,7 +964,7 @@ impl<'self, A, T: Iterator, B, U: Iterator> Iterator for return Some(x) } } - match self.iter.next().map_consume(self.f) { + match self.iter.next().map_consume(|x| (self.f)(x)) { None => return None, next => self.subiter = next, } diff --git a/src/libstd/local_data.rs b/src/libstd/local_data.rs index 33b4e3f1963a9..c5f2c8ae584d1 100644 --- a/src/libstd/local_data.rs +++ b/src/libstd/local_data.rs @@ -46,7 +46,7 @@ use task::local_data_priv::{local_get, local_pop, local_modify, local_set, Handl * * These two cases aside, the interface is safe. */ -pub type LocalDataKey<'self,T> = &'self fn(v: @T); +pub type LocalDataKey<'self,T> = &'self fn:Copy(v: @T); /** * Remove a task-local data value from the table, returning the diff --git a/src/libstd/os.rs b/src/libstd/os.rs index 400a93ee28f4e..1fbcda12dce14 100644 --- a/src/libstd/os.rs +++ b/src/libstd/os.rs @@ -595,7 +595,7 @@ pub fn walk_dir(p: &Path, f: &fn(&Path) -> bool) -> bool { let r = list_dir(p); r.iter().advance(|q| { let path = &p.push(*q); - f(path) && (!path_is_dir(path) || walk_dir(path, f)) + f(path) && (!path_is_dir(path) || walk_dir(path, |p| f(p))) }) } diff --git a/src/libstd/str.rs b/src/libstd/str.rs index 2144afc0fbd18..e47800d70c6b5 100644 --- a/src/libstd/str.rs +++ b/src/libstd/str.rs @@ -463,7 +463,7 @@ pub fn each_split_within<'a>(ss: &'a str, cont }; - ss.iter().enumerate().advance(machine); + ss.iter().enumerate().advance(|x| machine(x)); // Let the automaton 'run out' by supplying trailing whitespace let mut fake_i = ss.len(); @@ -761,7 +761,7 @@ impl<'self> StrUtil for &'self str { // NB: len includes the trailing null. assert!(len > 0); if unsafe { *(ptr::offset(buf,len-1)) != 0 } { - to_owned(self).as_c_str(f) + to_owned(self).as_c_str(|s| f(s)) } else { f(buf as *libc::c_char) } diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 8f06fede05722..c932a9660c2fd 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -230,11 +230,15 @@ fn each_ancestor(list: &mut AncestorList, // 'do_continue' - Did the forward_blk succeed at this point? (i.e., // should we recurse? or should our callers unwind?) + let forward_blk = Cell::new(forward_blk); + // The map defaults to None, because if ancestors is None, we're at // the end of the list, which doesn't make sense to coalesce. return do (**ancestors).map_default((None,false)) |ancestor_arc| { // NB: Takes a lock! (this ancestor node) do access_ancestors(ancestor_arc) |nobe| { + // Argh, but we couldn't give it to coalesce() otherwise. + let forward_blk = forward_blk.take(); // Check monotonicity assert!(last_generation > nobe.generation); /*##########################################################* diff --git a/src/libstd/to_bytes.rs b/src/libstd/to_bytes.rs index 6f0c615d007c2..d6e92dd679ea1 100644 --- a/src/libstd/to_bytes.rs +++ b/src/libstd/to_bytes.rs @@ -232,7 +232,8 @@ impl IterBytes for (A,B) { #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { - (ref a, ref b) => { a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) } + (ref a, ref b) => { a.iter_bytes(lsb0, |b| f(b)) && + b.iter_bytes(lsb0, |b| f(b)) } } } } @@ -242,7 +243,9 @@ impl IterBytes for (A,B,C) { fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { (ref a, ref b, ref c) => { - a.iter_bytes(lsb0, f) && b.iter_bytes(lsb0, f) && c.iter_bytes(lsb0, f) + a.iter_bytes(lsb0, |b| f(b)) && + b.iter_bytes(lsb0, |b| f(b)) && + c.iter_bytes(lsb0, |b| f(b)) } } } @@ -296,7 +299,7 @@ impl IterBytes for Option { #[inline] fn iter_bytes(&self, lsb0: bool, f: Cb) -> bool { match *self { - Some(ref a) => 0u8.iter_bytes(lsb0, f) && a.iter_bytes(lsb0, f), + Some(ref a) => 0u8.iter_bytes(lsb0, |b| f(b)) && a.iter_bytes(lsb0, |b| f(b)), None => 1u8.iter_bytes(lsb0, f) } } diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 8f70c75439a01..b9b03ea56619e 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -251,7 +251,7 @@ impl TrieNode { fn each<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { for uint::range(0, self.children.len()) |idx| { match self.children[idx] { - Internal(ref x) => if !x.each(f) { return false }, + Internal(ref x) => if !x.each(|i,t| f(i,t)) { return false }, External(k, ref v) => if !f(&k, v) { return false }, Nothing => () } @@ -262,7 +262,7 @@ impl TrieNode { fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { match self.children[idx - 1] { - Internal(ref x) => if !x.each_reverse(f) { return false }, + Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false }, External(k, ref v) => if !f(&k, v) { return false }, Nothing => () } @@ -273,7 +273,7 @@ impl TrieNode { fn mutate_values<'a>(&'a mut self, f: &fn(&uint, &mut T) -> bool) -> bool { for self.children.mut_iter().advance |child| { match *child { - Internal(ref mut x) => if !x.mutate_values(f) { + Internal(ref mut x) => if !x.mutate_values(|i,t| f(i,t)) { return false }, External(k, ref mut v) => if !f(&k, v) { return false }, diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index 8555d99255d5a..4e7943f7cfd2b 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -191,7 +191,7 @@ pub fn split(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut start = 0u; let mut result = ~[]; while start < ln { - match position_between(v, start, ln, f) { + match position_between(v, start, ln, |t| f(t)) { None => break, Some(i) => { result.push(v.slice(start, i).to_owned()); @@ -215,7 +215,7 @@ pub fn splitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut count = n; let mut result = ~[]; while start < ln && count > 0u { - match position_between(v, start, ln, f) { + match position_between(v, start, ln, |t| f(t)) { None => break, Some(i) => { result.push(v.slice(start, i).to_owned()); @@ -240,7 +240,7 @@ pub fn rsplit(v: &[T], f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut end = ln; let mut result = ~[]; while end > 0 { - match rposition_between(v, 0, end, f) { + match rposition_between(v, 0, end, |t| f(t)) { None => break, Some(i) => { result.push(v.slice(i + 1, end).to_owned()); @@ -265,7 +265,7 @@ pub fn rsplitn(v: &[T], n: uint, f: &fn(t: &T) -> bool) -> ~[~[T]] { let mut count = n; let mut result = ~[]; while end > 0u && count > 0u { - match rposition_between(v, 0u, end, f) { + match rposition_between(v, 0u, end, |t| f(t)) { None => break, Some(i) => { result.push(v.slice(i + 1u, end).to_owned()); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 8e1c51caf7c1a..bc432c4c7b0b6 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -17,17 +17,14 @@ use parse::token::{interner_get, str_to_ident}; use std::hashmap::HashMap; use std::option::Option; -use std::to_bytes::IterBytes; -use std::to_bytes; use std::to_str::ToStr; use extra::serialize::{Encodable, Decodable, Encoder, Decoder}; - // an identifier contains a Name (index into the interner // table) and a SyntaxContext to track renaming and // macro expansion per Flatt et al., "Macros // That Work Together" -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct ident { name: Name, ctxt: SyntaxContext } /// Construct an identifier with the given name and an empty context: @@ -57,7 +54,7 @@ pub struct SCTable { pub static empty_ctxt : uint = 0; pub static illegal_ctxt : uint = 1; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum SyntaxContext_ { EmptyCtxt, Mark (Mrk,SyntaxContext), @@ -86,42 +83,28 @@ impl Encodable for ident { } } +#[deriving(IterBytes)] impl Decodable for ident { fn decode(d: &mut D) -> ident { str_to_ident(d.read_str()) } } -impl to_bytes::IterBytes for ident { - #[inline] - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.name.iter_bytes(lsb0, f) - } -} - // Functions may or may not have names. pub type fn_ident = Option; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct Lifetime { id: node_id, span: span, ident: ident } -impl to_bytes::IterBytes for Lifetime { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.id.iter_bytes(lsb0, f) && - self.span.iter_bytes(lsb0, f) && - self.ident.iter_bytes(lsb0, f) - } -} - // a "Path" is essentially Rust's notion of a name; // for instance: core::cmp::Eq . It's represented // as a sequence of identifiers, along with a bunch // of supporting information. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct Path { span: span, global: bool, @@ -134,7 +117,7 @@ pub type crate_num = int; pub type node_id = int; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct def_id { crate: crate_num, node: node_id, @@ -143,7 +126,7 @@ pub struct def_id { pub static local_crate: crate_num = 0; pub static crate_node_id: node_id = 0; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] // The AST represents all type param bounds as types. // typeck::collect::compute_bounds matches these against // the "special" built-in traits (see middle::lang_items) and @@ -153,14 +136,14 @@ pub enum TyParamBound { RegionTyParamBound } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct TyParam { ident: ident, id: node_id, bounds: @OptVec } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct Generics { lifetimes: OptVec, ty_params: OptVec @@ -178,7 +161,7 @@ impl Generics { } } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum def { def_fn(def_id, purity), def_static_method(/* method */ def_id, @@ -216,7 +199,7 @@ pub type crate_cfg = ~[@meta_item]; pub type crate = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct crate_ { module: _mod, attrs: ~[attribute], @@ -225,7 +208,7 @@ pub struct crate_ { pub type meta_item = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum meta_item_ { meta_word(@str), meta_list(@str, ~[@meta_item]), @@ -234,7 +217,7 @@ pub enum meta_item_ { pub type blk = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct blk_ { view_items: ~[@view_item], stmts: ~[@stmt], @@ -243,40 +226,26 @@ pub struct blk_ { rules: blk_check_mode, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct pat { id: node_id, node: pat_, span: span, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct field_pat { ident: ident, pat: @pat, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum binding_mode { bind_by_ref(mutability), bind_infer } -impl to_bytes::IterBytes for binding_mode { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - bind_by_ref(ref m) => { - 0u8.iter_bytes(lsb0, f) && m.iter_bytes(lsb0, f) - } - - bind_infer => { - 1u8.iter_bytes(lsb0, f) - } - } - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum pat_ { pat_wild, // A pat_ident may either be a new bound variable, @@ -301,28 +270,16 @@ pub enum pat_ { pat_vec(~[@pat], Option<@pat>, ~[@pat]) } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum mutability { m_mutbl, m_imm, m_const, } -impl to_bytes::IterBytes for mutability { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum Sigil { BorrowedSigil, OwnedSigil, ManagedSigil } -impl to_bytes::IterBytes for Sigil { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as uint).iter_bytes(lsb0, f) - } -} - impl ToStr for Sigil { fn to_str(&self) -> ~str { match *self { @@ -333,7 +290,7 @@ impl ToStr for Sigil { } } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum vstore { // FIXME (#3469): Change uint to @expr (actually only constant exprs) vstore_fixed(Option), // [1,2,3,4] @@ -342,7 +299,7 @@ pub enum vstore { vstore_slice(Option<@Lifetime>) // &'foo? [1,2,3,4] } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum expr_vstore { expr_vstore_uniq, // ~[1,2,3,4] expr_vstore_box, // @[1,2,3,4] @@ -351,7 +308,7 @@ pub enum expr_vstore { expr_vstore_mut_slice, // &mut [1,2,3,4] } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum binop { add, subtract, @@ -373,7 +330,7 @@ pub enum binop { gt, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum unop { box(mutability), uniq(mutability), @@ -384,7 +341,7 @@ pub enum unop { pub type stmt = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum stmt_ { // could be an item or a local (let) binding: stmt_decl(@decl, node_id), @@ -401,7 +358,7 @@ pub enum stmt_ { // FIXME (pending discussion of #1697, #2178...): local should really be // a refinement on pat. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct local_ { is_mutbl: bool, ty: @Ty, @@ -414,7 +371,7 @@ pub type local = spanned; pub type decl = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum decl_ { // a local (let) binding: decl_local(@local), @@ -422,14 +379,14 @@ pub enum decl_ { decl_item(@item), } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct arm { pats: ~[@pat], guard: Option<@expr>, body: blk, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct field_ { ident: ident, expr: @expr, @@ -437,10 +394,10 @@ pub struct field_ { pub type field = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum blk_check_mode { default_blk, unsafe_blk, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct expr { id: node_id, node: expr_, @@ -460,14 +417,14 @@ impl expr { } } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum CallSugar { NoSugar, DoSugar, ForSugar } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum expr_ { expr_vstore(@expr, expr_vstore), expr_vec(~[@expr], mutability), @@ -538,7 +495,7 @@ pub enum expr_ { // else knows what to do with them, so you'll probably get a syntax // error. // -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] #[doc="For macro invocations; parsing is delegated to the macro"] pub enum token_tree { // a single token @@ -611,7 +568,7 @@ pub enum token_tree { // pub type matcher = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum matcher_ { // match one token match_tok(::parse::token::Token), @@ -624,14 +581,14 @@ pub enum matcher_ { pub type mac = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum mac_ { mac_invoc_tt(@Path,~[token_tree]), // new macro-invocation } pub type lit = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum lit_ { lit_str(@str), lit_int(i64, int_ty), @@ -645,13 +602,13 @@ pub enum lit_ { // NB: If you change this, you'll probably want to change the corresponding // type structure in middle/ty.rs as well. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct mt { ty: @Ty, mutbl: mutability, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct ty_field_ { ident: ident, mt: mt, @@ -659,7 +616,7 @@ pub struct ty_field_ { pub type ty_field = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct ty_method { ident: ident, attrs: ~[attribute], @@ -671,7 +628,7 @@ pub struct ty_method { span: span, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] // A trait method is either required (meaning it doesn't have an // implementation, just a signature) or provided (meaning it has a default // implementation). @@ -680,7 +637,7 @@ pub enum trait_method { provided(@method), } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum int_ty { ty_i, ty_char, ty_i8, ty_i16, ty_i32, ty_i64, } impl ToStr for int_ty { @@ -689,13 +646,7 @@ impl ToStr for int_ty { } } -impl to_bytes::IterBytes for int_ty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum uint_ty { ty_u, ty_u8, ty_u16, ty_u32, ty_u64, } impl ToStr for uint_ty { @@ -704,13 +655,7 @@ impl ToStr for uint_ty { } } -impl to_bytes::IterBytes for uint_ty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum float_ty { ty_f, ty_f32, ty_f64, } impl ToStr for float_ty { @@ -719,14 +664,8 @@ impl ToStr for float_ty { } } -impl to_bytes::IterBytes for float_ty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - // NB Eq method appears below. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct Ty { id: node_id, node: ty_, @@ -734,7 +673,7 @@ pub struct Ty { } // Not represented directly in the AST, referred to by name through a ty_path. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum prim_ty { ty_int(int_ty), ty_uint(uint_ty), @@ -743,12 +682,13 @@ pub enum prim_ty { ty_bool, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum Onceness { Once, Many } +#[deriving(IterBytes)] impl ToStr for Onceness { fn to_str(&self) -> ~str { match *self { @@ -758,13 +698,7 @@ impl ToStr for Onceness { } } -impl to_bytes::IterBytes for Onceness { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as uint).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct TyClosure { sigil: Sigil, region: Option<@Lifetime>, @@ -779,7 +713,7 @@ pub struct TyClosure { bounds: Option>, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct TyBareFn { purity: purity, abis: AbiSet, @@ -787,7 +721,7 @@ pub struct TyBareFn { decl: fn_decl } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum ty_ { ty_nil, ty_bot, /* bottom type */ @@ -808,19 +742,13 @@ pub enum ty_ { ty_infer, } -impl to_bytes::IterBytes for Ty { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.span.lo.iter_bytes(lsb0, f) && self.span.hi.iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum asm_dialect { asm_att, asm_intel } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct inline_asm { asm: @str, clobbers: @str, @@ -831,7 +759,7 @@ pub struct inline_asm { dialect: asm_dialect } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct arg { is_mutbl: bool, ty: @Ty, @@ -839,20 +767,21 @@ pub struct arg { id: node_id, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct fn_decl { inputs: ~[arg], output: @Ty, cf: ret_style, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum purity { unsafe_fn, // declared with "unsafe fn" impure_fn, // declared with "fn" extern_fn, // declared with "extern fn" } +#[deriving(IterBytes)] impl ToStr for purity { fn to_str(&self) -> ~str { match *self { @@ -863,26 +792,14 @@ impl ToStr for purity { } } -impl to_bytes::IterBytes for purity { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum ret_style { noreturn, // functions with return type _|_ that always // raise an error or exit (i.e. never return to the caller) return_val, // everything else } -impl to_bytes::IterBytes for ret_style { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (*self as u8).iter_bytes(lsb0, f) - } -} - -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum explicit_self_ { sty_static, // no self sty_value, // `self` @@ -891,27 +808,9 @@ pub enum explicit_self_ { sty_uniq(mutability) // `~self` } -impl to_bytes::IterBytes for explicit_self_ { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - sty_static => 0u8.iter_bytes(lsb0, f), - sty_value => 1u8.iter_bytes(lsb0, f), - sty_region(ref lft, ref mutbl) => { - 2u8.iter_bytes(lsb0, f) && lft.iter_bytes(lsb0, f) && mutbl.iter_bytes(lsb0, f) - } - sty_box(ref mutbl) => { - 3u8.iter_bytes(lsb0, f) && mutbl.iter_bytes(lsb0, f) - } - sty_uniq(ref mutbl) => { - 4u8.iter_bytes(lsb0, f) && mutbl.iter_bytes(lsb0, f) - } - } - } -} - pub type explicit_self = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct method { ident: ident, attrs: ~[attribute], @@ -926,17 +825,17 @@ pub struct method { vis: visibility, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct _mod { view_items: ~[@view_item], items: ~[@item], } // Foreign mods can be named or anonymous -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum foreign_mod_sort { named, anonymous } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct foreign_mod { sort: foreign_mod_sort, abis: AbiSet, @@ -944,24 +843,24 @@ pub struct foreign_mod { items: ~[@foreign_item], } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct variant_arg { ty: @Ty, id: node_id, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum variant_kind { tuple_variant_kind(~[variant_arg]), struct_variant_kind(@struct_def), } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct enum_def { variants: ~[variant], } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct variant_ { name: ident, attrs: ~[attribute], @@ -973,7 +872,7 @@ pub struct variant_ { pub type variant = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct path_list_ident_ { name: ident, id: node_id, @@ -983,7 +882,7 @@ pub type path_list_ident = spanned; pub type view_path = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum view_path_ { // quux = foo::bar::baz @@ -1000,7 +899,7 @@ pub enum view_path_ { view_path_list(@Path, ~[path_list_ident], node_id) } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct view_item { node: view_item_, attrs: ~[attribute], @@ -1008,7 +907,7 @@ pub struct view_item { span: span, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum view_item_ { view_item_extern_mod(ident, ~[@meta_item], node_id), view_item_use(~[@view_path]), @@ -1020,11 +919,11 @@ pub type attribute = spanned; // Distinguishes between attributes that decorate items and attributes that // are contained as statements within items. These two cases need to be // distinguished for pretty-printing. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum attr_style { attr_outer, attr_inner, } // doc-comments are promoted to attributes that have is_sugared_doc = true -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct attribute_ { style: attr_style, value: @meta_item, @@ -1038,13 +937,13 @@ pub struct attribute_ { If this impl is an item_impl, the impl_id is redundant (it could be the same as the impl's node id). */ -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct trait_ref { path: @Path, ref_id: node_id, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum visibility { public, private, inherited } impl visibility { @@ -1056,7 +955,7 @@ impl visibility { } } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct struct_field_ { kind: struct_field_kind, id: node_id, @@ -1066,13 +965,13 @@ pub struct struct_field_ { pub type struct_field = spanned; -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum struct_field_kind { named_field(ident, visibility), unnamed_field // element of a tuple-like struct } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct struct_def { fields: ~[@struct_field], /* fields, not including ctor */ /* ID of the constructor. This is only used for tuple- or enum-like @@ -1084,7 +983,7 @@ pub struct struct_def { FIXME (#3300): Should allow items to be anonymous. Right now we just use dummy names for anon items. */ -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct item { ident: ident, attrs: ~[attribute], @@ -1094,7 +993,7 @@ pub struct item { span: span, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum item_ { item_static(@Ty, mutability, @expr), item_fn(fn_decl, purity, AbiSet, Generics, blk), @@ -1112,7 +1011,7 @@ pub enum item_ { item_mac(mac), } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct foreign_item { ident: ident, attrs: ~[attribute], @@ -1122,7 +1021,7 @@ pub struct foreign_item { vis: visibility, } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum foreign_item_ { foreign_item_fn(fn_decl, purity, Generics), foreign_item_static(@Ty, /* is_mutbl */ bool), @@ -1131,7 +1030,7 @@ pub enum foreign_item_ { // The data we save and restore about an inlined item or method. This is not // part of the AST that we parse from a file, but it becomes part of the tree // that we trans. -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub enum inlined_item { ii_item(@item), ii_method(def_id /* impl id */, @method), diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index 6761736d2f374..9439f45be21bf 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -19,7 +19,6 @@ use visit; use std::hashmap::HashMap; use std::int; use std::option; -use std::to_bytes; use std::cast; use std::local_data; @@ -194,14 +193,6 @@ pub fn is_call_expr(e: @expr) -> bool { match e.node { expr_call(*) => true, _ => false } } -// This makes def_id hashable -impl to_bytes::IterBytes for def_id { - #[inline] - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.crate.iter_bytes(lsb0, f) && self.node.iter_bytes(lsb0, f) - } -} - pub fn block_from_expr(e: @expr) -> blk { let blk_ = default_block(~[], option::Some::<@expr>(e), e.id); return spanned {node: blk_, span: e.span}; @@ -544,18 +535,18 @@ pub fn walk_pat(pat: @pat, it: &fn(@pat) -> bool) -> bool { match pat.node { pat_ident(_, _, Some(p)) => walk_pat(p, it), pat_struct(_, ref fields, _) => { - fields.iter().advance(|f| walk_pat(f.pat, it)) + fields.iter().advance(|f| walk_pat(f.pat, |p| it(p))) } pat_enum(_, Some(ref s)) | pat_tup(ref s) => { - s.iter().advance(|&p| walk_pat(p, it)) + s.iter().advance(|&p| walk_pat(p, |p| it(p))) } pat_box(s) | pat_uniq(s) | pat_region(s) => { walk_pat(s, it) } pat_vec(ref before, ref slice, ref after) => { - before.iter().advance(|&p| walk_pat(p, it)) && - slice.iter().advance(|&p| walk_pat(p, it)) && - after.iter().advance(|&p| walk_pat(p, it)) + before.iter().advance(|&p| walk_pat(p, |p| it(p))) && + slice.iter().advance(|&p| walk_pat(p, |p| it(p))) && + after.iter().advance(|&p| walk_pat(p, |p| it(p))) } pat_wild | pat_lit(_) | pat_range(_, _) | pat_ident(_, _, _) | pat_enum(_, _) => { @@ -704,7 +695,7 @@ pub fn new_sctable_internal() -> SCTable { pub fn get_sctable() -> @mut SCTable { unsafe { let sctable_key = (cast::transmute::<(uint, uint), - &fn(v: @@mut SCTable)>( + &fn:Copy(v: @@mut SCTable)>( (-4 as uint, 0u))); match local_data::local_data_get(sctable_key) { None => { diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs index 5efc96e16b535..bcf617c56ae1e 100644 --- a/src/libsyntax/codemap.rs +++ b/src/libsyntax/codemap.rs @@ -22,7 +22,6 @@ source code snippets, etc. */ use std::cmp; -use std::to_bytes; use std::uint; use extra::serialize::{Encodable, Decodable, Encoder, Decoder}; @@ -32,12 +31,12 @@ pub trait Pos { } /// A byte offset -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct BytePos(uint); /// A character offset. Because of multibyte utf8 characters, a byte offset /// is not equivalent to a character offset. The CodeMap will convert BytePos /// values to CharPos values as necessary. -#[deriving(Eq)] +#[deriving(Eq,IterBytes)] pub struct CharPos(uint); // XXX: Lots of boilerplate in these impls, but so far my attempts to fix @@ -67,12 +66,6 @@ impl Sub for BytePos { } } -impl to_bytes::IterBytes for BytePos { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (**self).iter_bytes(lsb0, f) - } -} - impl Pos for CharPos { fn from_uint(n: uint) -> CharPos { CharPos(n) } fn to_uint(&self) -> uint { **self } @@ -85,12 +78,6 @@ impl cmp::Ord for CharPos { fn gt(&self, other: &CharPos) -> bool { **self > **other } } -impl to_bytes::IterBytes for CharPos { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - (**self).iter_bytes(lsb0, f) - } -} - impl Add for CharPos { fn add(&self, rhs: &CharPos) -> CharPos { CharPos(**self + **rhs) @@ -109,13 +96,14 @@ are *absolute* positions from the beginning of the codemap, not positions relative to FileMaps. Methods on the CodeMap can be used to relate spans back to the original source. */ +#[deriving(IterBytes)] pub struct span { lo: BytePos, hi: BytePos, expn_info: Option<@ExpnInfo> } -#[deriving(Eq, Encodable, Decodable)] +#[deriving(Eq, Encodable, Decodable,IterBytes)] pub struct spanned { node: T, span: span } impl cmp::Eq for span { @@ -138,14 +126,6 @@ impl Decodable for span { } } -impl to_bytes::IterBytes for span { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.lo.iter_bytes(lsb0, f) && - self.hi.iter_bytes(lsb0, f) && - self.expn_info.iter_bytes(lsb0, f) - } -} - pub fn spanned(lo: BytePos, hi: BytePos, t: T) -> spanned { respan(mk_sp(lo, hi), t) } @@ -191,40 +171,21 @@ pub struct LocWithOpt { // used to be structural records. Better names, anyone? pub struct FileMapAndLine {fm: @FileMap, line: uint} pub struct FileMapAndBytePos {fm: @FileMap, pos: BytePos} +#[deriving(IterBytes)] pub struct NameAndSpan {name: @str, span: Option} -impl to_bytes::IterBytes for NameAndSpan { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.name.iter_bytes(lsb0, f) && self.span.iter_bytes(lsb0, f) - } -} - +#[deriving(IterBytes)] pub struct CallInfo { call_site: span, callee: NameAndSpan } -impl to_bytes::IterBytes for CallInfo { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - self.call_site.iter_bytes(lsb0, f) && self.callee.iter_bytes(lsb0, f) - } -} - /// Extra information for tracking macro expansion of spans +#[deriving(IterBytes)] pub enum ExpnInfo { ExpandedFrom(CallInfo) } -impl to_bytes::IterBytes for ExpnInfo { - fn iter_bytes(&self, lsb0: bool, f: to_bytes::Cb) -> bool { - match *self { - ExpandedFrom(ref call_info) => { - 0u8.iter_bytes(lsb0, f) && call_info.iter_bytes(lsb0, f) - } - } - } -} - pub type FileName = @str; pub struct FileLines diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs index 282a28ff9e07d..78fdb99753d40 100644 --- a/src/libsyntax/ext/base.rs +++ b/src/libsyntax/ext/base.rs @@ -509,7 +509,7 @@ impl MapChain{ } }, ConsMapChain (~ref mut map, rest) => { - if satisfies_pred(map,&n,pred) { + if satisfies_pred(map,&n,|v|pred(v)) { map.insert(key,ext); } else { rest.insert_into_frame(key,ext,n,pred) diff --git a/src/libsyntax/ext/deriving/iter_bytes.rs b/src/libsyntax/ext/deriving/iter_bytes.rs index 8403234f89252..15fb6ee9ff77a 100644 --- a/src/libsyntax/ext/deriving/iter_bytes.rs +++ b/src/libsyntax/ext/deriving/iter_bytes.rs @@ -43,15 +43,21 @@ pub fn expand_deriving_iter_bytes(cx: @ExtCtxt, } fn iter_bytes_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { - let lsb0_f = match substr.nonself_args { - [l, f] => ~[l, f], + let (lsb0, f)= match substr.nonself_args { + [l, f] => (l, f), _ => cx.span_bug(span, "Incorrect number of arguments in `deriving(IterBytes)`") }; + // Build the "explicitly borrowed" stack closure, "|_buf| f(_buf)". + let blk_arg = cx.ident_of("_buf"); + let borrowed_f = + cx.lambda_expr_1(span, cx.expr_call(span, f, ~[cx.expr_ident(span, blk_arg)]), + blk_arg); + let iter_bytes_ident = substr.method_ident; let call_iterbytes = |thing_expr| { cx.expr_method_call(span, thing_expr, iter_bytes_ident, - copy lsb0_f) + ~[lsb0, borrowed_f]) }; let mut exprs = ~[]; let fields; diff --git a/src/libsyntax/ext/deriving/rand.rs b/src/libsyntax/ext/deriving/rand.rs index dfbc028ddf6af..19aa29a62a9c0 100644 --- a/src/libsyntax/ext/deriving/rand.rs +++ b/src/libsyntax/ext/deriving/rand.rs @@ -99,7 +99,7 @@ fn rand_substructure(cx: @ExtCtxt, span: span, substr: &Substructure) -> @expr { (ident, ref summary) => { cx.arm(span, ~[ pat ], - rand_thing(cx, span, ident, summary, rand_call)) + rand_thing(cx, span, ident, summary, || rand_call())) } } }; diff --git a/src/libsyntax/opt_vec.rs b/src/libsyntax/opt_vec.rs index fe050fc99f19d..bf8c5ae462bf0 100644 --- a/src/libsyntax/opt_vec.rs +++ b/src/libsyntax/opt_vec.rs @@ -18,7 +18,7 @@ use std::vec::VecIterator; -#[deriving(Encodable, Decodable)] +#[deriving(Encodable, Decodable,IterBytes)] pub enum OptVec { Empty, Vec(~[T]) diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs index 793626f0e1808..94147825da49c 100644 --- a/src/libsyntax/parse/token.rs +++ b/src/libsyntax/parse/token.rs @@ -22,7 +22,7 @@ use std::local_data; use std::rand; use std::rand::RngUtil; -#[deriving(Encodable, Decodable, Eq)] +#[deriving(Encodable, Decodable, Eq, IterBytes)] pub enum binop { PLUS, MINUS, @@ -36,7 +36,7 @@ pub enum binop { SHR, } -#[deriving(Encodable, Decodable, Eq)] +#[deriving(Encodable, Decodable, Eq, IterBytes)] pub enum Token { /* Expression-operator symbols. */ EQ, @@ -97,7 +97,7 @@ pub enum Token { EOF, } -#[deriving(Encodable, Decodable, Eq)] +#[deriving(Encodable, Decodable, Eq, IterBytes)] /// For interpolation during macro expansion. pub enum nonterminal { nt_item(@ast::item), @@ -484,7 +484,7 @@ pub fn get_ident_interner() -> @ident_interner { unsafe { let key = (cast::transmute::<(uint, uint), - &fn(v: @@::parse::token::ident_interner)>( + &fn:Copy(v: @@::parse::token::ident_interner)>( (-3 as uint, 0u))); match local_data::local_data_get(key) { Some(interner) => *interner, diff --git a/src/test/compile-fail/kindck-owned.rs b/src/test/compile-fail/kindck-owned.rs index 3f859b7dc84e6..848fd95a5607a 100644 --- a/src/test/compile-fail/kindck-owned.rs +++ b/src/test/compile-fail/kindck-owned.rs @@ -29,6 +29,6 @@ fn main() { copy2(boxed); let owned: ~fn() = || {}; copy2(owned); //~ ERROR does not fulfill `Copy` - let borrowed: &fn() = || {}; + let borrowed: &fn:Copy() = || {}; copy2(borrowed); //~ ERROR does not fulfill `'static` } diff --git a/src/test/compile-fail/regions-creating-enums.rs b/src/test/compile-fail/regions-creating-enums.rs index 2ab0c14b49b65..c2d8427d5eb39 100644 --- a/src/test/compile-fail/regions-creating-enums.rs +++ b/src/test/compile-fail/regions-creating-enums.rs @@ -33,8 +33,8 @@ fn map_nums(x: &ast, f: &fn(uint) -> uint) -> &ast { return &num(f(x)); //~ ERROR borrowed value does not live long enough } add(x, y) => { - let m_x = map_nums(x, f); - let m_y = map_nums(y, f); + let m_x = map_nums(x, |z| f(z)); + let m_y = map_nums(y, |z| f(z)); return &add(m_x, m_y); //~ ERROR borrowed value does not live long enough } } diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs b/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs new file mode 100644 index 0000000000000..bfb1e910495de --- /dev/null +++ b/src/test/compile-fail/the-case-of-the-recurring-closure-2.rs @@ -0,0 +1,44 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Tests correct kind-checking of the reason stack closures without the :Copy +// bound must be noncopyable. For details see +// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/ + +struct R<'self> { + // This struct is needed to create the + // otherwise infinite type of a fn that + // accepts itself as argument: + c: &'self fn:Copy(&R, bool) +} + +fn innocent_looking_victim() { + let mut x = Some(~"hello"); + do conspirator |f, writer| { + if writer { + x = None; //~ ERROR cannot implicitly borrow + } else { + match x { + Some(ref msg) => { + (f.c)(f, true); + println(fmt!("%?", msg)); + }, + None => fail!("oops"), + } + } + } +} + +fn conspirator(f: &fn:Copy(&R, bool)) { + let r = R {c: f}; + f(&r, false) +} + +fn main() { innocent_looking_victim() } diff --git a/src/test/compile-fail/the-case-of-the-recurring-closure.rs b/src/test/compile-fail/the-case-of-the-recurring-closure.rs new file mode 100644 index 0000000000000..f05c30c3355e0 --- /dev/null +++ b/src/test/compile-fail/the-case-of-the-recurring-closure.rs @@ -0,0 +1,44 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Tests correct kind-checking of the reason stack closures without the :Copy +// bound must be noncopyable. For details see +// http://smallcultfollowing.com/babysteps/blog/2013/04/30/the-case-of-the-recurring-closure/ + +struct R<'self> { + // This struct is needed to create the + // otherwise infinite type of a fn that + // accepts itself as argument: + c: &'self fn(&R, bool) +} + +fn innocent_looking_victim() { + let mut x = Some(~"hello"); + do conspirator |f, writer| { + if writer { + x = None; + } else { + match x { + Some(ref msg) => { + (f.c)(f, true); + println(fmt!("%?", msg)); + }, + None => fail!("oops"), + } + } + } +} + +fn conspirator(f: &fn(&R, bool)) { + let r = R {c: f}; + f(&r, false) //~ ERROR use of moved value +} + +fn main() { innocent_looking_victim() }