auto merge of #7363 : bblum/rust/soundness, r=nikomatsakis
The commit f9a5453 is meant to be a temporary hold-over. Whether or not there is added a way for the compiler to "implicitly borrow" stack closures in this way, there should be a codegen optimization that prevents having to traverse possibly-very-many function pointers to find the function you ultimately wanted to call. I tried to separate out the changes so this particular commit could be straight-up reverted if auto-borrowing happens in the future. r? @nikomatsakis
This commit is contained in:
commit
132cfcdd88
src
libextra
librust
librustc
libstd
libsyntax
test/compile-fail
@ -66,9 +66,9 @@ pub fn traverse<K, V: Copy>(m: Treemap<K, V>, 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
|
@ -42,7 +42,8 @@ pub fn merge_sort<T:Copy>(v: &[T], le: Le<T>) -> ~[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<T:Copy>(le: Le<T>, a: &[T], b: &[T]) -> ~[T] {
|
||||
@ -83,10 +84,10 @@ fn qsort<T>(arr: &mut [T], left: uint,
|
||||
right: uint, compare_func: Le<T>) {
|
||||
if right > left {
|
||||
let pivot = (left + right) / 2u;
|
||||
let new_pivot = part::<T>(arr, left, right, pivot, compare_func);
|
||||
let new_pivot = part::<T>(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::<T>(arr, left, new_pivot - 1u, compare_func);
|
||||
qsort::<T>(arr, left, new_pivot - 1u, |x,y| compare_func(x,y));
|
||||
}
|
||||
qsort::<T>(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]
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
|
@ -511,14 +511,14 @@ impl<K: TotalOrd, V> TreeNode<K, V> {
|
||||
|
||||
fn each<'r, K: TotalOrd, V>(node: &'r Option<~TreeNode<K, V>>,
|
||||
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<K, V>>,
|
||||
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<K, V>>,
|
||||
@ -527,9 +527,9 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode<K, V>>,
|
||||
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
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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<ty::t>)
|
||||
{
|
||||
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`",
|
||||
|
@ -901,7 +901,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(*)) |
|
||||
@ -912,12 +912,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));
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
@ -941,7 +941,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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -953,7 +953,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));
|
||||
}
|
||||
}
|
||||
|
||||
@ -967,15 +967,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));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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<creader_cache_key, t>;
|
||||
|
||||
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<ast::ident>,
|
||||
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<Region>;
|
||||
* - `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<ty::t>,
|
||||
@ -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,
|
||||
|
@ -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 });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -671,7 +671,7 @@ impl<T:Hash + Eq> Set<T> for HashSet<T> {
|
||||
fn symmetric_difference(&self,
|
||||
other: &HashSet<T>,
|
||||
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<T:Hash + Eq> Set<T> for HashSet<T> {
|
||||
|
||||
/// Visit the values representing the union
|
||||
fn union(&self, other: &HashSet<T>, 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))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -964,7 +964,7 @@ impl<'self, A, T: Iterator<A>, B, U: Iterator<B>> Iterator<B> 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,
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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);
|
||||
/*##########################################################*
|
||||
|
@ -232,7 +232,8 @@ impl<A:IterBytes,B:IterBytes> 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<A:IterBytes,B:IterBytes,C:IterBytes> 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<A:IterBytes> IterBytes for Option<A> {
|
||||
#[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)
|
||||
}
|
||||
}
|
||||
|
@ -251,7 +251,7 @@ impl<T> TrieNode<T> {
|
||||
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<T> TrieNode<T> {
|
||||
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<T> TrieNode<T> {
|
||||
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 },
|
||||
|
@ -191,7 +191,7 @@ pub fn split<T:Copy>(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<T:Copy>(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<T:Copy>(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<T:Copy>(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());
|
||||
|
@ -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<S:Encoder> Encodable<S> for ident {
|
||||
}
|
||||
}
|
||||
|
||||
#[deriving(IterBytes)]
|
||||
impl<D:Decoder> Decodable<D> 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<ident>;
|
||||
|
||||
#[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<TyParamBound>
|
||||
}
|
||||
|
||||
#[deriving(Eq, Encodable, Decodable)]
|
||||
#[deriving(Eq, Encodable, Decodable,IterBytes)]
|
||||
pub struct Generics {
|
||||
lifetimes: OptVec<Lifetime>,
|
||||
ty_params: OptVec<TyParam>
|
||||
@ -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<crate_>;
|
||||
|
||||
#[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<meta_item_>;
|
||||
|
||||
#[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<blk_>;
|
||||
|
||||
#[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<uint>), // [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<stmt_>;
|
||||
|
||||
#[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<local_>;
|
||||
|
||||
pub type decl = spanned<decl_>;
|
||||
|
||||
#[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<field_>;
|
||||
|
||||
#[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<matcher_>;
|
||||
|
||||
#[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<mac_>;
|
||||
|
||||
#[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<lit_>;
|
||||
|
||||
#[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<ty_field_>;
|
||||
|
||||
#[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<OptVec<TyParamBound>>,
|
||||
}
|
||||
|
||||
#[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<explicit_self_>;
|
||||
|
||||
#[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<variant_>;
|
||||
|
||||
#[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<path_list_ident_>;
|
||||
|
||||
pub type view_path = spanned<view_path_>;
|
||||
|
||||
#[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<attribute_>;
|
||||
// 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<struct_field_>;
|
||||
|
||||
#[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),
|
||||
|
@ -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 => {
|
||||
|
@ -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<BytePos, BytePos> 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<CharPos,CharPos> 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<T> { node: T, span: span }
|
||||
|
||||
impl cmp::Eq for span {
|
||||
@ -138,14 +126,6 @@ impl<D:Decoder> Decodable<D> 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<T>(lo: BytePos, hi: BytePos, t: T) -> spanned<T> {
|
||||
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<span>}
|
||||
|
||||
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
|
||||
|
@ -509,7 +509,7 @@ impl <K: Eq + Hash + IterBytes ,V: Copy> MapChain<K,V>{
|
||||
}
|
||||
},
|
||||
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)
|
||||
|
@ -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;
|
||||
|
@ -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()))
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -18,7 +18,7 @@
|
||||
|
||||
use std::vec::VecIterator;
|
||||
|
||||
#[deriving(Encodable, Decodable)]
|
||||
#[deriving(Encodable, Decodable,IterBytes)]
|
||||
pub enum OptVec<T> {
|
||||
Empty,
|
||||
Vec(~[T])
|
||||
|
@ -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,
|
||||
|
@ -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`
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
44
src/test/compile-fail/the-case-of-the-recurring-closure-2.rs
Normal file
44
src/test/compile-fail/the-case-of-the-recurring-closure-2.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() }
|
44
src/test/compile-fail/the-case-of-the-recurring-closure.rs
Normal file
44
src/test/compile-fail/the-case-of-the-recurring-closure.rs
Normal file
@ -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 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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() }
|
Loading…
x
Reference in New Issue
Block a user