auto merge of #6223 : alexcrichton/rust/issue-6183, r=pcwalton

Closes #6183.

The first commit changes the compiler's method of treating a `for` loop, and all the remaining commits are just dealing with the fallout.

The biggest fallout was the `IterBytes` trait, although it's really a whole lot nicer now because all of the `iter_bytes_XX` methods are just and-ed together. Sadly there was a huge amount of stuff that's `cfg(stage0)` gated, but whoever lands the next snapshot is going to have a lot of fun deleting all this code!
This commit is contained in:
bors 2013-05-10 17:56:02 -07:00
commit 3e0400fb86
73 changed files with 2948 additions and 309 deletions

View file

@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use ast::{meta_item, item, expr};
use ast::{meta_item, item, expr, and};
use codemap::span;
use ext::base::ext_ctxt;
use ext::build;
@ -31,7 +31,7 @@ pub fn expand_deriving_iter_bytes(cx: @ext_ctxt,
Literal(Path::new(~[~"bool"])),
Literal(Path::new(~[~"core", ~"to_bytes", ~"Cb"]))
],
ret_ty: nil_ty(),
ret_ty: Literal(Path::new(~[~"bool"])),
const_nonmatching: false,
combine_substructure: iter_bytes_substructure
}
@ -58,13 +58,11 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) ->
};
let iter_bytes_ident = substr.method_ident;
let call_iterbytes = |thing_expr| {
build::mk_stmt(
cx, span,
build::mk_method_call(cx, span,
thing_expr, iter_bytes_ident,
copy lsb0_f))
build::mk_method_call(cx, span,
thing_expr, iter_bytes_ident,
copy lsb0_f)
};
let mut stmts = ~[];
let mut exprs = ~[];
let fields;
match *substr.fields {
Struct(ref fs) => {
@ -78,7 +76,7 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) ->
None => build::mk_uint(cx, span, index)
};
stmts.push(call_iterbytes(discriminant));
exprs.push(call_iterbytes(discriminant));
fields = fs;
}
@ -86,8 +84,14 @@ fn iter_bytes_substructure(cx: @ext_ctxt, span: span, substr: &Substructure) ->
}
for fields.each |&(_, field, _)| {
stmts.push(call_iterbytes(field));
exprs.push(call_iterbytes(field));
}
build::mk_block(cx, span, ~[], stmts, None)
if exprs.len() == 0 {
cx.span_bug(span, "#[deriving(IterBytes)] needs at least one field");
}
do vec::foldl(exprs[0], exprs.slice(1, exprs.len())) |prev, me| {
build::mk_binary(cx, span, and, prev, *me)
}
}

View file

@ -195,18 +195,8 @@ pub fn expand_item(extsbox: @mut SyntaxEnv,
}
// does this attribute list contain "macro_escape" ?
pub fn contains_macro_escape (attrs: &[ast::attribute]) -> bool{
let mut accum = false;
do attrs.each |attr| {
let mname = attr::get_attr_name(attr);
if (mname == @~"macro_escape") {
accum = true;
false
} else {
true
}
}
accum
pub fn contains_macro_escape (attrs: &[ast::attribute]) -> bool {
attrs.any(|attr| "macro_escape" == *attr::get_attr_name(attr))
}
// this macro disables (one layer of) macro

View file

@ -100,6 +100,7 @@ pub impl state_ {
/// Iterate over the states that can be reached in one message
/// from this state.
#[cfg(stage0)]
fn reachable(&self, f: &fn(state) -> bool) {
for self.messages.each |m| {
match *m {
@ -111,6 +112,21 @@ pub impl state_ {
}
}
}
/// Iterate over the states that can be reached in one message
/// from this state.
#[cfg(not(stage0))]
fn reachable(&self, f: &fn(state) -> bool) -> bool {
for self.messages.each |m| {
match *m {
message(_, _, _, _, Some(next_state { state: ref id, _ })) => {
let state = self.proto.get_state((*id));
if !f(state) { return false; }
}
_ => ()
}
}
return true;
}
}
pub type protocol = @mut protocol_;