<commit_before>// Code that generates a test runner to run all the tests in a crate

import std::option;
import std::ivec;
import syntax::ast;
import syntax::fold;
import front::attr;

export modify_for_testing;

type node_id_gen = @fn() -> ast::node_id;

type test_ctxt = @rec(node_id_gen next_node_id,
                      mutable ast::ident[] path,
                      mutable ast::ident[][] testfns);

// Traverse the crate, collecting all the test functions, eliding any
// existing main functions, and synthesizing a main test harness
fn modify_for_testing(@ast::crate crate) -> @ast::crate {

    // FIXME: This hackasaurus assumes that 200000 is a safe number to start
    // generating node_ids at (which is totally not the case). pauls is going
    // to land a patch that puts parse_sess into session, which will give us
    // access to the real next node_id.
    auto next_node_id = @mutable 200000;
    auto next_node_id_fn = @bind fn(@mutable ast::node_id next_node_id)
        -> ast::node_id {
        auto this_node_id = *next_node_id;
        *next_node_id = next_node_id + 1;
        ret this_node_id;
    } (next_node_id);

    let test_ctxt cx = @rec(next_node_id = next_node_id_fn,
                            mutable path = ~[],
                            mutable testfns = ~[]);

    auto precursor = rec(fold_crate = bind fold_crate(cx, _, _),
                         fold_item = bind fold_item(cx, _, _),
                         fold_mod = bind fold_mod(cx, _, _)
                         with *fold::default_ast_fold());

    auto fold = fold::make_fold(precursor);
    auto res = @fold.fold_crate(*crate);
    // FIXME: This is necessary to break a circular reference
    fold::dummy_out(fold);
    ret res;
}

fn fold_mod(&test_ctxt cx, &ast::_mod m,
            fold::ast_fold fld) -> ast::_mod {

    // Remove any defined main function from the AST so it doesn't clash with
    // the one we're going to add.  FIXME: This is sloppy. Instead we should
    // have some mechanism to indicate to the translation pass which function
    // we want to be main.
    fn nomain(&@ast::item item) -> option::t[@ast::item] {
        alt (item.node) {
            ast::item_fn(?f, _) {
                if (item.ident == "main") { option::none }
                else { option::some(item) }
            }
            _ { option::some(item) }
        }
    }

    auto mod_nomain = rec(view_items=m.view_items,
                          items=ivec::filter_map(nomain, m.items));
    ret fold::noop_fold_mod(mod_nomain, fld);
}

fn fold_crate(&test_ctxt cx, &ast::crate_ c,
              fold::ast_fold fld) -> ast::crate_ {
    auto folded = fold::noop_fold_crate(c, fld);

    // Add a special __test module to the crate that will contain code
    // generated for the test harness
    ret rec(module = add_test_module(cx, folded.module)
            with folded);
}

fn fold_item(&test_ctxt cx, &@ast::item i,
             fold::ast_fold fld) -> @ast::item {

    cx.path += ~[i.ident];
    log #fmt("current path: %s", ast::path_name_i(cx.path));

    if (is_test_fn(i)) {
        log "this is a test function";
        cx.testfns += ~[cx.path];
        log #fmt("have %u test functions", ivec::len(cx.testfns));
    }

    auto res = fold::noop_fold_item(i, fld);
    ivec::pop(cx.path);
    ret res;
}

fn is_test_fn(&@ast::item i) -> bool {
    auto has_test_attr =
        ivec::len(attr::find_attrs_by_name(i.attrs, "test")) > 0u;

    fn has_test_signature(&@ast::item i) -> bool {
        alt (i.node) {
            case (ast::item_fn(?f, ?tps)) {
                auto input_cnt = ivec::len(f.decl.inputs);
                auto no_output = f.decl.output.node == ast::ty_nil;
                auto tparm_cnt = ivec::len(tps);
                input_cnt == 0u && no_output && tparm_cnt == 0u
            }
            case (_) { false }
        }
    }

    ret has_test_attr && has_test_signature(i);
}

fn add_test_module(&test_ctxt cx, &ast::_mod m) -> ast::_mod {
    auto testmod = mk_test_module(cx);
    ret rec(items=m.items + ~[testmod] with m);
}

/*

We're going to be building a module that looks more or less like:

mod __test {

  fn main(vec[str] args) -> int {
    std::test::test_main(args, tests())
  }

  fn tests() -> std::test::test_desc[] {
    ... the list of tests in the crate ...
  }
}

*/

fn mk_test_module(&test_ctxt cx) -> @ast::item {
    // A function that generates a vector of test descriptors to feed to the
    // test runner
    auto testsfn = mk_tests(cx);
    // The synthesized main function which will call the console test runner
    // with our list of tests
    auto mainfn = mk_main(cx);
    let ast::_mod testmod = rec(view_items=~[],
                                items=~[mainfn, testsfn]);
    auto item_ = ast::item_mod(testmod);
    let ast::item item = rec(ident = "__test",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn nospan[T](&T t) -> ast::spanned[T] {
    ret rec(node=t,
            span=rec(lo=0u,hi=0u));
}

fn mk_tests(&test_ctxt cx) -> @ast::item {
    auto ret_ty = mk_test_desc_ivec_ty();

    let ast::fn_decl decl = rec(inputs = ~[],
                                output = ret_ty,
                                purity = ast::impure_fn,
                                cf = ast::return,
                                constraints = ~[]);
    auto proto = ast::proto_fn;

    // The vector of test_descs for this crate
    auto test_descs = mk_test_desc_vec(cx);

    let ast::block_ body_= rec(stmts = ~[],
                               expr = option::some(test_descs),
                               id = cx.next_node_id());
    auto body = nospan(body_);

    auto fn_ = rec(decl = decl,
                   proto = proto,
                   body = body);

    auto item_ = ast::item_fn(fn_, ~[]);
    let ast::item item = rec(ident = "tests",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn empty_fn_ty() -> ast::ty {
    auto proto = ast::proto_fn;
    auto input_ty = ~[];
    auto ret_ty = @nospan(ast::ty_nil);
    auto cf = ast::return;
    auto constrs = ~[];
    ret nospan(ast::ty_fn(proto, input_ty, ret_ty, cf, constrs));
}

// The ast::ty of std::test::test_desc
fn mk_test_desc_ivec_ty() -> @ast::ty {
    // Oh this is brutal to build by hand
    let ast::mt name_mt = rec(ty = @nospan(ast::ty_str),
                              mut = ast::imm);
    let ast::mt fn_mt = rec(ty = @empty_fn_ty(),
                            mut = ast::imm);

    let ast::ty_field_ name_ty_field_ = rec(ident = "name",
                                            mt = name_mt);

    let ast::ty_field_ fn_ty_field_ = rec(ident = "fn",
                                          mt = fn_mt);

    let ast::ty_field[] test_desc_fields = ~[nospan(name_ty_field_),
                                             nospan(fn_ty_field_)];
    let ast::ty test_desc_ty = nospan(ast::ty_rec(test_desc_fields));

    let ast::mt ivec_mt = rec(ty = @test_desc_ty,
                              mut = ast::imm);

    ret @nospan(ast::ty_ivec(ivec_mt));
}

fn mk_test_desc_vec(&test_ctxt cx) -> @ast::expr {
    log #fmt("building test vector from %u tests",
             ivec::len(cx.testfns));
    auto descs = ~[];
    for (ast::ident[] testpath in cx.testfns) {
        log #fmt("encoding %s", ast::path_name_i(testpath));
        auto path = testpath;
        descs += ~[mk_test_desc_rec(cx, path)];
    }

    ret @rec(id = cx.next_node_id(),
             node = ast::expr_vec(descs, ast::imm, ast::sk_unique),
             span = rec(lo=0u,hi=0u));
}

fn mk_test_desc_rec(&test_ctxt cx, ast::ident[] path) -> @ast::expr {

    let ast::lit name_lit = nospan(ast::lit_str(ast::path_name_i(path),
                                                ast::sk_rc));
    let ast::expr name_expr = rec(id = cx.next_node_id(),
                                  node = ast::expr_lit(@name_lit),
                                  span = rec(lo=0u, hi=0u));

    let ast::field name_field = nospan(rec(mut = ast::imm,
                                           ident = "name",
                                           expr = @name_expr));

    let ast::path fn_path = nospan(rec(global = false,
                                       idents = path,
                                       types = ~[]));

    let ast::expr fn_expr = rec(id = cx.next_node_id(),
                                node = ast::expr_path(fn_path),
                                span = rec(lo=0u, hi=0u));

    let ast::field fn_field = nospan(rec(mut = ast::imm,
                                         ident = "fn",
                                         expr = @fn_expr));

    let ast::expr_ desc_rec_ = ast::expr_rec(~[name_field, fn_field],
                                             option::none);
    let ast::expr desc_rec = rec(id = cx.next_node_id(),
                                 node = desc_rec_,
                                 span = rec(lo=0u, hi=0u));
    ret @desc_rec;
}

fn mk_main(&test_ctxt cx) -> @ast::item {

    let ast::mt args_mt = rec(ty = @nospan(ast::ty_str),
                              mut = ast::imm);
    let ast::ty args_ty = nospan(ast::ty_vec(args_mt));

    let ast::arg args_arg = rec(mode = ast::val,
                                ty = @args_ty,
                                ident = "args",
                                id = cx.next_node_id());

    auto ret_ty = nospan(ast::ty_int);

    let ast::fn_decl decl = rec(inputs = ~[args_arg],
                                output = @ret_ty,
                                purity = ast::impure_fn,
                                cf = ast::return,
                                constraints = ~[]);
    auto proto = ast::proto_fn;

    auto test_main_call_expr = mk_test_main_call(cx);

    let ast::block_ body_ = rec(stmts = ~[],
                                expr = option::some(test_main_call_expr),
                                id = cx.next_node_id());
    auto body = rec(node = body_, span = rec(lo=0u, hi=0u));

    auto fn_ = rec(decl = decl,
                   proto = proto,
                   body = body);

    auto item_ = ast::item_fn(fn_, ~[]);
    let ast::item item = rec(ident = "main",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn mk_test_main_call(&test_ctxt cx) -> @ast::expr {

    // Get the args passed to main so we can pass the to test_main
    let ast::path args_path = nospan(rec(global = false,
                                         idents = ~["args"],
                                         types = ~[]));

    let ast::expr_ args_path_expr_ = ast::expr_path(args_path);

    let ast::expr args_path_expr = rec(id = cx.next_node_id(),
                                       node = args_path_expr_,
                                       span = rec(lo=0u, hi=0u));

    // Call __test::test to generate the vector of test_descs
    let ast::path test_path = nospan(rec(global = false,
                                         idents = ~["tests"],
                                         types = ~[]));

    let ast::expr_ test_path_expr_ = ast::expr_path(test_path);

    let ast::expr test_path_expr = rec(id = cx.next_node_id(),
                                       node = test_path_expr_,
                                       span = rec(lo=0u, hi=0u));

    let ast::expr_ test_call_expr_ = ast::expr_call(@test_path_expr, ~[]);

    let ast::expr test_call_expr = rec(id = cx.next_node_id(),
                                       node = test_call_expr_,
                                       span = rec(lo=0u, hi=0u));

    // Call std::test::test_main
    let ast::path test_main_path = nospan(rec(global = false,
                                              idents = ~["std",
                                                         "test",
                                                         "test_main"],
                                              types = ~[]));

    let ast::expr_ test_main_path_expr_
        = ast::expr_path(test_main_path);

    let ast::expr test_main_path_expr = rec(id = cx.next_node_id(),
                                            node = test_main_path_expr_,
                                            span = rec(lo=0u, hi=0u));

    let ast::expr_ test_main_call_expr_
        = ast::expr_call(@test_main_path_expr, ~[@args_path_expr,
                                                 @test_call_expr]);

    let ast::expr test_main_call_expr = rec(id = cx.next_node_id(),
                                            node = test_main_call_expr_,
                                            span = rec(lo=0u, hi=0u));

    ret @test_main_call_expr;
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Log the synthesized __test module. Issue #428<commit_after>// Code that generates a test runner to run all the tests in a crate

import std::option;
import std::ivec;
import syntax::ast;
import syntax::fold;
import syntax::print::pprust;
import front::attr;

export modify_for_testing;

type node_id_gen = @fn() -> ast::node_id;

type test_ctxt = @rec(node_id_gen next_node_id,
                      mutable ast::ident[] path,
                      mutable ast::ident[][] testfns);

// Traverse the crate, collecting all the test functions, eliding any
// existing main functions, and synthesizing a main test harness
fn modify_for_testing(@ast::crate crate) -> @ast::crate {

    // FIXME: This hackasaurus assumes that 200000 is a safe number to start
    // generating node_ids at (which is totally not the case). pauls is going
    // to land a patch that puts parse_sess into session, which will give us
    // access to the real next node_id.
    auto next_node_id = @mutable 200000;
    auto next_node_id_fn = @bind fn(@mutable ast::node_id next_node_id)
        -> ast::node_id {
        auto this_node_id = *next_node_id;
        *next_node_id = next_node_id + 1;
        ret this_node_id;
    } (next_node_id);

    let test_ctxt cx = @rec(next_node_id = next_node_id_fn,
                            mutable path = ~[],
                            mutable testfns = ~[]);

    auto precursor = rec(fold_crate = bind fold_crate(cx, _, _),
                         fold_item = bind fold_item(cx, _, _),
                         fold_mod = bind fold_mod(cx, _, _)
                         with *fold::default_ast_fold());

    auto fold = fold::make_fold(precursor);
    auto res = @fold.fold_crate(*crate);
    // FIXME: This is necessary to break a circular reference
    fold::dummy_out(fold);
    ret res;
}

fn fold_mod(&test_ctxt cx, &ast::_mod m,
            fold::ast_fold fld) -> ast::_mod {

    // Remove any defined main function from the AST so it doesn't clash with
    // the one we're going to add.  FIXME: This is sloppy. Instead we should
    // have some mechanism to indicate to the translation pass which function
    // we want to be main.
    fn nomain(&@ast::item item) -> option::t[@ast::item] {
        alt (item.node) {
            ast::item_fn(?f, _) {
                if (item.ident == "main") { option::none }
                else { option::some(item) }
            }
            _ { option::some(item) }
        }
    }

    auto mod_nomain = rec(view_items=m.view_items,
                          items=ivec::filter_map(nomain, m.items));
    ret fold::noop_fold_mod(mod_nomain, fld);
}

fn fold_crate(&test_ctxt cx, &ast::crate_ c,
              fold::ast_fold fld) -> ast::crate_ {
    auto folded = fold::noop_fold_crate(c, fld);

    // Add a special __test module to the crate that will contain code
    // generated for the test harness
    ret rec(module = add_test_module(cx, folded.module)
            with folded);
}

fn fold_item(&test_ctxt cx, &@ast::item i,
             fold::ast_fold fld) -> @ast::item {

    cx.path += ~[i.ident];
    log #fmt("current path: %s", ast::path_name_i(cx.path));

    if (is_test_fn(i)) {
        log "this is a test function";
        cx.testfns += ~[cx.path];
        log #fmt("have %u test functions", ivec::len(cx.testfns));
    }

    auto res = fold::noop_fold_item(i, fld);
    ivec::pop(cx.path);
    ret res;
}

fn is_test_fn(&@ast::item i) -> bool {
    auto has_test_attr =
        ivec::len(attr::find_attrs_by_name(i.attrs, "test")) > 0u;

    fn has_test_signature(&@ast::item i) -> bool {
        alt (i.node) {
            case (ast::item_fn(?f, ?tps)) {
                auto input_cnt = ivec::len(f.decl.inputs);
                auto no_output = f.decl.output.node == ast::ty_nil;
                auto tparm_cnt = ivec::len(tps);
                input_cnt == 0u && no_output && tparm_cnt == 0u
            }
            case (_) { false }
        }
    }

    ret has_test_attr && has_test_signature(i);
}

fn add_test_module(&test_ctxt cx, &ast::_mod m) -> ast::_mod {
    auto testmod = mk_test_module(cx);
    ret rec(items=m.items + ~[testmod] with m);
}

/*

We're going to be building a module that looks more or less like:

mod __test {

  fn main(vec[str] args) -> int {
    std::test::test_main(args, tests())
  }

  fn tests() -> std::test::test_desc[] {
    ... the list of tests in the crate ...
  }
}

*/

fn mk_test_module(&test_ctxt cx) -> @ast::item {
    // A function that generates a vector of test descriptors to feed to the
    // test runner
    auto testsfn = mk_tests(cx);
    // The synthesized main function which will call the console test runner
    // with our list of tests
    auto mainfn = mk_main(cx);
    let ast::_mod testmod = rec(view_items=~[],
                                items=~[mainfn, testsfn]);
    auto item_ = ast::item_mod(testmod);
    let ast::item item = rec(ident = "__test",
                              attrs = ~[],
                              id = cx.next_node_id(),
                              node = item_,
                              span = rec(lo=0u, hi=0u));

    log #fmt("Synthetic test module:\n%s\n", pprust::item_to_str(@item));

    ret @item;
}

fn nospan[T](&T t) -> ast::spanned[T] {
    ret rec(node=t,
            span=rec(lo=0u,hi=0u));
}

fn mk_tests(&test_ctxt cx) -> @ast::item {
    auto ret_ty = mk_test_desc_ivec_ty();

    let ast::fn_decl decl = rec(inputs = ~[],
                                output = ret_ty,
                                purity = ast::impure_fn,
                                cf = ast::return,
                                constraints = ~[]);
    auto proto = ast::proto_fn;

    // The vector of test_descs for this crate
    auto test_descs = mk_test_desc_vec(cx);

    let ast::block_ body_= rec(stmts = ~[],
                               expr = option::some(test_descs),
                               id = cx.next_node_id());
    auto body = nospan(body_);

    auto fn_ = rec(decl = decl,
                   proto = proto,
                   body = body);

    auto item_ = ast::item_fn(fn_, ~[]);
    let ast::item item = rec(ident = "tests",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn empty_fn_ty() -> ast::ty {
    auto proto = ast::proto_fn;
    auto input_ty = ~[];
    auto ret_ty = @nospan(ast::ty_nil);
    auto cf = ast::return;
    auto constrs = ~[];
    ret nospan(ast::ty_fn(proto, input_ty, ret_ty, cf, constrs));
}

// The ast::ty of std::test::test_desc
fn mk_test_desc_ivec_ty() -> @ast::ty {
    // Oh this is brutal to build by hand
    let ast::mt name_mt = rec(ty = @nospan(ast::ty_str),
                              mut = ast::imm);
    let ast::mt fn_mt = rec(ty = @empty_fn_ty(),
                            mut = ast::imm);

    let ast::ty_field_ name_ty_field_ = rec(ident = "name",
                                            mt = name_mt);

    let ast::ty_field_ fn_ty_field_ = rec(ident = "fn",
                                          mt = fn_mt);

    let ast::ty_field[] test_desc_fields = ~[nospan(name_ty_field_),
                                             nospan(fn_ty_field_)];
    let ast::ty test_desc_ty = nospan(ast::ty_rec(test_desc_fields));

    let ast::mt ivec_mt = rec(ty = @test_desc_ty,
                              mut = ast::imm);

    ret @nospan(ast::ty_ivec(ivec_mt));
}

fn mk_test_desc_vec(&test_ctxt cx) -> @ast::expr {
    log #fmt("building test vector from %u tests",
             ivec::len(cx.testfns));
    auto descs = ~[];
    for (ast::ident[] testpath in cx.testfns) {
        log #fmt("encoding %s", ast::path_name_i(testpath));
        auto path = testpath;
        descs += ~[mk_test_desc_rec(cx, path)];
    }

    ret @rec(id = cx.next_node_id(),
             node = ast::expr_vec(descs, ast::imm, ast::sk_unique),
             span = rec(lo=0u,hi=0u));
}

fn mk_test_desc_rec(&test_ctxt cx, ast::ident[] path) -> @ast::expr {

    let ast::lit name_lit = nospan(ast::lit_str(ast::path_name_i(path),
                                                ast::sk_rc));
    let ast::expr name_expr = rec(id = cx.next_node_id(),
                                  node = ast::expr_lit(@name_lit),
                                  span = rec(lo=0u, hi=0u));

    let ast::field name_field = nospan(rec(mut = ast::imm,
                                           ident = "name",
                                           expr = @name_expr));

    let ast::path fn_path = nospan(rec(global = false,
                                       idents = path,
                                       types = ~[]));

    let ast::expr fn_expr = rec(id = cx.next_node_id(),
                                node = ast::expr_path(fn_path),
                                span = rec(lo=0u, hi=0u));

    let ast::field fn_field = nospan(rec(mut = ast::imm,
                                         ident = "fn",
                                         expr = @fn_expr));

    let ast::expr_ desc_rec_ = ast::expr_rec(~[name_field, fn_field],
                                             option::none);
    let ast::expr desc_rec = rec(id = cx.next_node_id(),
                                 node = desc_rec_,
                                 span = rec(lo=0u, hi=0u));
    ret @desc_rec;
}

fn mk_main(&test_ctxt cx) -> @ast::item {

    let ast::mt args_mt = rec(ty = @nospan(ast::ty_str),
                              mut = ast::imm);
    let ast::ty args_ty = nospan(ast::ty_vec(args_mt));

    let ast::arg args_arg = rec(mode = ast::val,
                                ty = @args_ty,
                                ident = "args",
                                id = cx.next_node_id());

    auto ret_ty = nospan(ast::ty_int);

    let ast::fn_decl decl = rec(inputs = ~[args_arg],
                                output = @ret_ty,
                                purity = ast::impure_fn,
                                cf = ast::return,
                                constraints = ~[]);
    auto proto = ast::proto_fn;

    auto test_main_call_expr = mk_test_main_call(cx);

    let ast::block_ body_ = rec(stmts = ~[],
                                expr = option::some(test_main_call_expr),
                                id = cx.next_node_id());
    auto body = rec(node = body_, span = rec(lo=0u, hi=0u));

    auto fn_ = rec(decl = decl,
                   proto = proto,
                   body = body);

    auto item_ = ast::item_fn(fn_, ~[]);
    let ast::item item = rec(ident = "main",
                             attrs = ~[],
                             id = cx.next_node_id(),
                             node = item_,
                             span = rec(lo=0u, hi=0u));
    ret @item;
}

fn mk_test_main_call(&test_ctxt cx) -> @ast::expr {

    // Get the args passed to main so we can pass the to test_main
    let ast::path args_path = nospan(rec(global = false,
                                         idents = ~["args"],
                                         types = ~[]));

    let ast::expr_ args_path_expr_ = ast::expr_path(args_path);

    let ast::expr args_path_expr = rec(id = cx.next_node_id(),
                                       node = args_path_expr_,
                                       span = rec(lo=0u, hi=0u));

    // Call __test::test to generate the vector of test_descs
    let ast::path test_path = nospan(rec(global = false,
                                         idents = ~["tests"],
                                         types = ~[]));

    let ast::expr_ test_path_expr_ = ast::expr_path(test_path);

    let ast::expr test_path_expr = rec(id = cx.next_node_id(),
                                       node = test_path_expr_,
                                       span = rec(lo=0u, hi=0u));

    let ast::expr_ test_call_expr_ = ast::expr_call(@test_path_expr, ~[]);

    let ast::expr test_call_expr = rec(id = cx.next_node_id(),
                                       node = test_call_expr_,
                                       span = rec(lo=0u, hi=0u));

    // Call std::test::test_main
    let ast::path test_main_path = nospan(rec(global = false,
                                              idents = ~["std",
                                                         "test",
                                                         "test_main"],
                                              types = ~[]));

    let ast::expr_ test_main_path_expr_
        = ast::expr_path(test_main_path);

    let ast::expr test_main_path_expr = rec(id = cx.next_node_id(),
                                            node = test_main_path_expr_,
                                            span = rec(lo=0u, hi=0u));

    let ast::expr_ test_main_call_expr_
        = ast::expr_call(@test_main_path_expr, ~[@args_path_expr,
                                                 @test_call_expr]);

    let ast::expr test_main_call_expr = rec(id = cx.next_node_id(),
                                            node = test_main_call_expr_,
                                            span = rec(lo=0u, hi=0u));

    ret @test_main_call_expr;
}

// Local Variables:
// mode: rust
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C $RBUILD 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before><commit_msg>Add regression test for issue #17651<commit_after>// Copyright 2014 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.

// Test that moves of unsized values within closures are caught
// and rejected.

fn main() {
    (|| box *[0u].as_slice())();
    //~^ ERROR cannot move a value of type [uint]
}
<|endoftext|>


<commit_before><commit_msg>Moved dsp-chain stuff into its own module behind a feature gate<commit_after>extern crate dsp;

use {Synth, instrument, oscillator};
use self::dsp::Sample;

impl<FRM, M, NFG, W, A, F, FW> dsp::Node<FRM> for Synth<M, NFG, W, A, F, FW>
    where FRM: dsp::Frame,
          <FRM::Sample as Sample>::Float: dsp::FromSample<f32>,
          <FRM::Sample as Sample>::Signed: dsp::FromSample<f32>,
          M: instrument::Mode,
          NFG: instrument::NoteFreqGenerator,
          W: oscillator::Waveform,
          A: oscillator::Amplitude,
          F: oscillator::Frequency,
          FW: oscillator::FreqWarp,
{
    #[inline]
    fn audio_requested(&mut self, output: &mut [FRM], sample_hz: f64) {
        self.fill_slice(output, sample_hz);
    }
}
<|endoftext|>


<commit_before><commit_msg>refactor error handler<commit_after><|endoftext|>


<commit_before>// Copyright 2014 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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this
one is too specific or the ordering is incorrect.

For example, the following `match` block has too many arms:

```compile_fail
match foo {
    Some(bar) => {/* ... */}
    None => {/* ... */}
    _ => {/* ... */} // All possible cases have already been handled
}
```

`match` blocks have their patterns matched in order, so, for example, putting
a wildcard arm above a more specific arm will make the latter arm irrelevant.

Ensure the ordering of the match arm is correct and remove any superfluous
arms.
"##,

E0002: r##"
This error indicates that an empty match expression is invalid because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired. This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`. So, the following will work:

```
enum Empty {}

fn foo(x: Empty) {
    match x {
        // empty
    }
}
```

However, this won't:

```compile_fail
enum Empty {}

fn foo(x: Option<String>) {
    match x {
        // empty
    }
}
```
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. So, the following will not compile:

```compile_fail
const NAN: f32 = 0.0 / 0.0;

let number = 0.1f32;

match number {
    NAN => { /* ... */ },
    _ => {}
}
```

To match against NaN values, you should instead use the `is_nan()` method in a
guard, like so:

```
let number = 0.1f32;

match number {
    x if x.is_nan() => { /* ... */ }
    _ => {}
}
```
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution. Erroneous code example:

```compile_fail
enum Terminator {
    HastaLaVistaBaby,
    TalkToMyHand,
}

let x = Terminator::HastaLaVistaBaby;

match x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered
    Terminator::TalkToMyHand => {}
}
```

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else". Example:

```
enum Terminator {
    HastaLaVistaBaby,
    TalkToMyHand,
}

let x = Terminator::HastaLaVistaBaby;

match x {
    Terminator::TalkToMyHand => {}
    Terminator::HastaLaVistaBaby => {}
}

// or:

match x {
    Terminator::TalkToMyHand => {}
    _ => {}
}
```
"##,

E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee
that a name will be extracted in all cases. Erroneous code example:

```compile_fail
let x = Some(1);
let Some(y) = x;
// error: refutable pattern in local binding: `None` not covered
```

If you encounter this error you probably need to use a `match` or `if let` to
deal with the possibility of failure. Example:

```compile_fail
let x = Some(1);

match x {
    Some(y) => {
        // do something
    },
    None => {}
}

// or:

if let Some(y) = x {
    // do something
}
```
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code
like the following is invalid as it requires the entire `Option<String>` to be
moved into a variable called `op_string` while simultaneously requiring the
inner `String` to be moved into a variable called `s`.

```compile_fail
let x = Some("s".to_string());

match x {
    op_string @ Some(s) => {},
    None => {},
}
```

See also the error E0303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

```compile_fail
match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => {}, // use s.
    _ => {},
}
```

The variable `s` has type `String`, and its use in the guard is as a variable of
type `String`. The guard code effectively executes in a separate scope to the
body of the arm, so the value would be moved into this anonymous scope and
therefore become unavailable in the body of the arm. Although this example seems
innocuous, the problem is most clear when considering functions that take their
argument by value.

```compile_fail
match Some("hi".to_string()) {
    Some(s) if { drop(s); false } => (),
    Some(s) => {}, // use s.
    _ => {},
}
```

The value would be dropped in the guard then become unavailable not only in the
body of that arm but also in all subsequent arms! The solution is to bind by
reference when using guards or refactor the entire expression, perhaps by
putting the condition inside the body of the arm.
"##,

E0009: r##"
In a pattern, all values that don't implement the `Copy` trait have to be bound
the same way. The goal here is to avoid binding simultaneously by-move and
by-ref.

This limitation may be removed in a future version of Rust.

Erroneous code example:

```compile_fail
struct X { x: (), }

let x = Some((X { x: () }, X { x: () }));
match x {
    Some((y, ref z)) => {},
    None => panic!()
}
```

You have two solutions:

Solution #1: Bind the pattern's values the same way.

```
struct X { x: (), }

let x = Some((X { x: () }, X { x: () }));
match x {
    Some((ref y, ref z)) => {},
    // or Some((y, z)) => {}
    None => panic!()
}
```

Solution #2: Implement the `Copy` trait for the `X` structure.

However, please keep in mind that the first solution should be preferred.

```
#[derive(Clone, Copy)]
struct X { x: (), }

let x = Some((X { x: () }, X { x: () }));
match x {
    Some((y, ref z)) => {},
    None => panic!()
}
```
"##,

E0158: r##"
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.

The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.

If you want to match against a `static`, consider using a guard instead:

```
static FORTY_TWO: i32 = 42;

match Some(42) {
    Some(x) if x == FORTY_TWO => {}
    _ => {}
}
```
"##,

E0162: r##"
An if-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular `let`-binding instead. For instance:

```compile_fail
struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
    // This body will always be executed.
    foo(x);
}
```

Try this instead:

```ignore
struct Irrefutable(i32);
let irr = Irrefutable(0);

let Irrefutable(x) = irr;
foo(x);
```
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular `let`-binding inside a `loop` instead. For instance:

```compile_fail
struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
    ...
}

Try this instead:

```
struct Irrefutable(i32);
let irr = Irrefutable(0);

loop {
    let Irrefutable(x) = irr;
    ...
}
```
"##,

E0170: r##"
Enum variants are qualified by default. For example, given this type:

```
enum Method {
    GET,
    POST,
}
```

You would match it using:

```
enum Method {
    GET,
    POST,
}

let m = Method::GET;

match m {
    Method::GET => {},
    Method::POST => {},
}
```

If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so `rustc` warns when
that happens.

Qualified names are good practice, and most code works well with them. But if
you prefer them unqualified, you can import the variants into scope:

```ignore
use Method::*;
enum Method { GET, POST }
```

If you want others to be able to import variants from your module directly, use
`pub use`:

```ignore
pub use Method::*;
enum Method { GET, POST }
```
"##,

E0297: r##"
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:

```compile_fail
let xs : Vec<Option<i32>> = vec!(Some(1), None);

// This fails because `None` is not covered.
for Some(x) in xs {
    // ...
}
```

Match inside the loop instead:

```
let xs : Vec<Option<i32>> = vec!(Some(1), None);

for item in xs {
    match item {
        Some(x) => {},
        None => {},
    }
}
```

Or use `if let`:

```
let xs : Vec<Option<i32>> = vec!(Some(1), None);

for item in xs {
    if let Some(x) = item {
        // ...
    }
}
```
"##,

E0301: r##"
Mutable borrows are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:

```compile_fail
match Some(()) {
    None => { },
    option if option.take().is_none() => {
        /* impossible, option is `Some` */
    },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
```
"##,

E0302: r##"
Assignments are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments
were allowed:

```compile_fail
match Some(()) {
    None => { },
    option if { option = None; false } { },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
```
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

```ignore
// Before.
match Some("hi".to_string()) {
    ref op_string_ref @ Some(s) => {},
    None => {},
}

// After.
match Some("hi".to_string()) {
    Some(ref s) => {
        let op_string_ref = &Some(s);
        // ...
    },
    None => {},
}
```

The `op_string_ref` binding has type `&Option<&String>` in both cases.

See also https://github.com/rust-lang/rust/issues/14587
"##,

E0306: r##"
In an array literal `[x; N]`, `N` is the number of elements in the array. This
must be an unsigned integer. Erroneous code example:

```compile_fail
let x = [0i32; true]; // error: expected positive integer for repeat count,
                      //        found boolean
```

Working example:

```
let x = [0i32; 2];
```
"##,

E0307: r##"
The length of an array is part of its type. For this reason, this length must
be a compile-time constant. Erroneous code example:

```compile_fail
    let len = 10;
    let x = [0i32; len]; // error: expected constant integer for repeat count,
                         //        found variable
```
"##,

}

register_diagnostics! {
E0298, // mismatched types between arms
E0299, // mismatched types between arms
E0471, // constant evaluation error: ..
}
<commit_msg>add help on pattern guard<commit_after>// Copyright 2014 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.

#![allow(non_snake_case)]

// Error messages for EXXXX errors.
// Each message should start and end with a new line, and be wrapped to 80 characters.
// In vim you can `:set tw=80` and use `gq` to wrap paragraphs. Use `:set tw=0` to disable.
register_long_diagnostics! {

E0001: r##"
This error suggests that the expression arm corresponding to the noted pattern
will never be reached as for all possible values of the expression being
matched, one of the preceding patterns will match.

This means that perhaps some of the preceding patterns are too general, this
one is too specific or the ordering is incorrect.

For example, the following `match` block has too many arms:

```compile_fail
match foo {
    Some(bar) => {/* ... */}
    None => {/* ... */}
    _ => {/* ... */} // All possible cases have already been handled
}
```

`match` blocks have their patterns matched in order, so, for example, putting
a wildcard arm above a more specific arm will make the latter arm irrelevant.

Ensure the ordering of the match arm is correct and remove any superfluous
arms.
"##,

E0002: r##"
This error indicates that an empty match expression is invalid because the type
it is matching on is non-empty (there exist values of this type). In safe code
it is impossible to create an instance of an empty type, so empty match
expressions are almost never desired. This error is typically fixed by adding
one or more cases to the match expression.

An example of an empty type is `enum Empty { }`. So, the following will work:

```
enum Empty {}

fn foo(x: Empty) {
    match x {
        // empty
    }
}
```

However, this won't:

```compile_fail
enum Empty {}

fn foo(x: Option<String>) {
    match x {
        // empty
    }
}
```
"##,

E0003: r##"
Not-a-Number (NaN) values cannot be compared for equality and hence can never
match the input to a match expression. So, the following will not compile:

```compile_fail
const NAN: f32 = 0.0 / 0.0;

let number = 0.1f32;

match number {
    NAN => { /* ... */ },
    _ => {}
}
```

To match against NaN values, you should instead use the `is_nan()` method in a
guard, like so:

```
let number = 0.1f32;

match number {
    x if x.is_nan() => { /* ... */ }
    _ => {}
}
```
"##,

E0004: r##"
This error indicates that the compiler cannot guarantee a matching pattern for
one or more possible inputs to a match expression. Guaranteed matches are
required in order to assign values to match expressions, or alternatively,
determine the flow of execution. Erroneous code example:

```compile_fail
enum Terminator {
    HastaLaVistaBaby,
    TalkToMyHand,
}

let x = Terminator::HastaLaVistaBaby;

match x { // error: non-exhaustive patterns: `HastaLaVistaBaby` not covered
    Terminator::TalkToMyHand => {}
}
```

If you encounter this error you must alter your patterns so that every possible
value of the input type is matched. For types with a small number of variants
(like enums) you should probably cover all cases explicitly. Alternatively, the
underscore `_` wildcard pattern can be added after all other patterns to match
"anything else". Example:

```
enum Terminator {
    HastaLaVistaBaby,
    TalkToMyHand,
}

let x = Terminator::HastaLaVistaBaby;

match x {
    Terminator::TalkToMyHand => {}
    Terminator::HastaLaVistaBaby => {}
}

// or:

match x {
    Terminator::TalkToMyHand => {}
    _ => {}
}
```
"##,

E0005: r##"
Patterns used to bind names must be irrefutable, that is, they must guarantee
that a name will be extracted in all cases. Erroneous code example:

```compile_fail
let x = Some(1);
let Some(y) = x;
// error: refutable pattern in local binding: `None` not covered
```

If you encounter this error you probably need to use a `match` or `if let` to
deal with the possibility of failure. Example:

```compile_fail
let x = Some(1);

match x {
    Some(y) => {
        // do something
    },
    None => {}
}

// or:

if let Some(y) = x {
    // do something
}
```
"##,

E0007: r##"
This error indicates that the bindings in a match arm would require a value to
be moved into more than one location, thus violating unique ownership. Code
like the following is invalid as it requires the entire `Option<String>` to be
moved into a variable called `op_string` while simultaneously requiring the
inner `String` to be moved into a variable called `s`.

```compile_fail
let x = Some("s".to_string());

match x {
    op_string @ Some(s) => {},
    None => {},
}
```

See also the error E0303.
"##,

E0008: r##"
Names bound in match arms retain their type in pattern guards. As such, if a
name is bound by move in a pattern, it should also be moved to wherever it is
referenced in the pattern guard code. Doing so however would prevent the name
from being available in the body of the match arm. Consider the following:

```compile_fail
match Some("hi".to_string()) {
    Some(s) if s.len() == 0 => {}, // use s.
    _ => {},
}
```

The variable `s` has type `String`, and its use in the guard is as a variable of
type `String`. The guard code effectively executes in a separate scope to the
body of the arm, so the value would be moved into this anonymous scope and
therefore becomes unavailable in the body of the arm.

The problem above can be solved by using the `ref` keyword.

```
match Some("hi".to_string()) {
    Some(ref s) if s.len() == 0 => {},
    _ => {},
}
```

Though this example seems innocuous and easy to solve, the problem becomes clear
when it encounters functions which consume the value:

```compile_fail
struct A{}

impl A {
    fn consume(self) -> usize {
        0
    }
}

fn main() {
    let a = Some(A{});
    match a {
        Some(y) if y.consume() > 0 => {}
        _ => {}
    }
}
```

In this situation, even the `ref` keyword cannot solve it, since borrowed
content cannot be moved. This problem cannot be solved generally. If the value
can be cloned, here is a not-so-specific solution:

```
#[derive(Clone)]
struct A{}

impl A {
    fn consume(self) -> usize {
        0
    }
}

fn main() {
    let a = Some(A{});
    match a{
        Some(ref y) if y.clone().consume() > 0 => {}
        _ => {}
    }
}
```

If the value will be consumed in the pattern guard, using its clone will not
move its ownership, so the code works.
"##,

E0009: r##"
In a pattern, all values that don't implement the `Copy` trait have to be bound
the same way. The goal here is to avoid binding simultaneously by-move and
by-ref.

This limitation may be removed in a future version of Rust.

Erroneous code example:

```compile_fail
struct X { x: (), }

let x = Some((X { x: () }, X { x: () }));
match x {
    Some((y, ref z)) => {},
    None => panic!()
}
```

You have two solutions:

Solution #1: Bind the pattern's values the same way.

```
struct X { x: (), }

let x = Some((X { x: () }, X { x: () }));
match x {
    Some((ref y, ref z)) => {},
    // or Some((y, z)) => {}
    None => panic!()
}
```

Solution #2: Implement the `Copy` trait for the `X` structure.

However, please keep in mind that the first solution should be preferred.

```
#[derive(Clone, Copy)]
struct X { x: (), }

let x = Some((X { x: () }, X { x: () }));
match x {
    Some((y, ref z)) => {},
    None => panic!()
}
```
"##,

E0158: r##"
`const` and `static` mean different things. A `const` is a compile-time
constant, an alias for a literal value. This property means you can match it
directly within a pattern.

The `static` keyword, on the other hand, guarantees a fixed location in memory.
This does not always mean that the value is constant. For example, a global
mutex can be declared `static` as well.

If you want to match against a `static`, consider using a guard instead:

```
static FORTY_TWO: i32 = 42;

match Some(42) {
    Some(x) if x == FORTY_TWO => {}
    _ => {}
}
```
"##,

E0162: r##"
An if-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular `let`-binding instead. For instance:

```compile_fail
struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
if let Irrefutable(x) = irr {
    // This body will always be executed.
    foo(x);
}
```

Try this instead:

```ignore
struct Irrefutable(i32);
let irr = Irrefutable(0);

let Irrefutable(x) = irr;
foo(x);
```
"##,

E0165: r##"
A while-let pattern attempts to match the pattern, and enters the body if the
match was successful. If the match is irrefutable (when it cannot fail to
match), use a regular `let`-binding inside a `loop` instead. For instance:

```compile_fail
struct Irrefutable(i32);
let irr = Irrefutable(0);

// This fails to compile because the match is irrefutable.
while let Irrefutable(x) = irr {
    ...
}

Try this instead:

```
struct Irrefutable(i32);
let irr = Irrefutable(0);

loop {
    let Irrefutable(x) = irr;
    ...
}
```
"##,

E0170: r##"
Enum variants are qualified by default. For example, given this type:

```
enum Method {
    GET,
    POST,
}
```

You would match it using:

```
enum Method {
    GET,
    POST,
}

let m = Method::GET;

match m {
    Method::GET => {},
    Method::POST => {},
}
```

If you don't qualify the names, the code will bind new variables named "GET" and
"POST" instead. This behavior is likely not what you want, so `rustc` warns when
that happens.

Qualified names are good practice, and most code works well with them. But if
you prefer them unqualified, you can import the variants into scope:

```ignore
use Method::*;
enum Method { GET, POST }
```

If you want others to be able to import variants from your module directly, use
`pub use`:

```ignore
pub use Method::*;
enum Method { GET, POST }
```
"##,

E0297: r##"
Patterns used to bind names must be irrefutable. That is, they must guarantee
that a name will be extracted in all cases. Instead of pattern matching the
loop variable, consider using a `match` or `if let` inside the loop body. For
instance:

```compile_fail
let xs : Vec<Option<i32>> = vec!(Some(1), None);

// This fails because `None` is not covered.
for Some(x) in xs {
    // ...
}
```

Match inside the loop instead:

```
let xs : Vec<Option<i32>> = vec!(Some(1), None);

for item in xs {
    match item {
        Some(x) => {},
        None => {},
    }
}
```

Or use `if let`:

```
let xs : Vec<Option<i32>> = vec!(Some(1), None);

for item in xs {
    if let Some(x) = item {
        // ...
    }
}
```
"##,

E0301: r##"
Mutable borrows are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if mutable
borrows were allowed:

```compile_fail
match Some(()) {
    None => { },
    option if option.take().is_none() => {
        /* impossible, option is `Some` */
    },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
```
"##,

E0302: r##"
Assignments are not allowed in pattern guards, because matching cannot have
side effects. Side effects could alter the matched object or the environment
on which the match depends in such a way, that the match would not be
exhaustive. For instance, the following would not match any arm if assignments
were allowed:

```compile_fail
match Some(()) {
    None => { },
    option if { option = None; false } { },
    Some(_) => { } // When the previous match failed, the option became `None`.
}
```
"##,

E0303: r##"
In certain cases it is possible for sub-bindings to violate memory safety.
Updates to the borrow checker in a future version of Rust may remove this
restriction, but for now patterns must be rewritten without sub-bindings.

```ignore
// Before.
match Some("hi".to_string()) {
    ref op_string_ref @ Some(s) => {},
    None => {},
}

// After.
match Some("hi".to_string()) {
    Some(ref s) => {
        let op_string_ref = &Some(s);
        // ...
    },
    None => {},
}
```

The `op_string_ref` binding has type `&Option<&String>` in both cases.

See also https://github.com/rust-lang/rust/issues/14587
"##,

E0306: r##"
In an array literal `[x; N]`, `N` is the number of elements in the array. This
must be an unsigned integer. Erroneous code example:

```compile_fail
let x = [0i32; true]; // error: expected positive integer for repeat count,
                      //        found boolean
```

Working example:

```
let x = [0i32; 2];
```
"##,

E0307: r##"
The length of an array is part of its type. For this reason, this length must
be a compile-time constant. Erroneous code example:

```compile_fail
    let len = 10;
    let x = [0i32; len]; // error: expected constant integer for repeat count,
                         //        found variable
```
"##,

}

register_diagnostics! {
E0298, // mismatched types between arms
E0299, // mismatched types between arms
E0471, // constant evaluation error: ..
}
<|endoftext|>


<commit_before>use util;

pub trait Executor {
    fn execute<F>(&self, f: F)
        where F: FnOnce() + Send + 'static,
              Self: Sized
    {
        self.execute_boxed(Box::new(f))
    }

    fn execute_boxed(&self, f: Box<ExecuteCallback>);
}

impl<T: Executor + ?Sized> Executor for Box<T> {
    fn execute_boxed(&self, f: Box<ExecuteCallback>) {
        (**self).execute_boxed(f)
    }
}

pub trait ExecuteCallback: Send + 'static {
    fn call(self: Box<Self>);
}

impl<F: FnOnce() + Send + 'static> ExecuteCallback for F {
    fn call(self: Box<F>) {
        (*self)()
    }
}

pub struct DefaultExecutor;

impl Executor for DefaultExecutor {
    fn execute<F: FnOnce() + Send + 'static>(&self, f: F) {
        f()
    }

    fn execute_boxed(&self, f: Box<ExecuteCallback>) {
        f.call()
    }
}

pub struct CatchUnwindExecutor;

impl Executor for CatchUnwindExecutor {
    fn execute<F: FnOnce() + Send + 'static>(&self, f: F) {
        let res = util::recover::<_, _, i32>(f);
        drop(res);
    }

    fn execute_boxed(&self, f: Box<ExecuteCallback>) {
        let res = util::recover::<_, _, i32>(|| f.call());
        drop(res);
    }
}
<commit_msg>Add an executor which limits recursion<commit_after>use std::cell::{Cell, RefCell};
use std::sync::Arc;

pub trait Executor: Send + Sync + 'static {
    fn execute<F>(&self, f: F)
        where F: FnOnce() + Send + 'static,
              Self: Sized
    {
        self.execute_boxed(Box::new(f))
    }

    fn execute_boxed(&self, f: Box<ExecuteCallback>);
}

impl<T: Executor + ?Sized + Send + Sync + 'static> Executor for Box<T> {
    fn execute_boxed(&self, f: Box<ExecuteCallback>) {
        (**self).execute_boxed(f)
    }
}

impl<T: Executor + ?Sized + Send + Sync + 'static> Executor for Arc<T> {
    fn execute_boxed(&self, f: Box<ExecuteCallback>) {
        (**self).execute_boxed(f)
    }
}

pub trait ExecuteCallback: Send + 'static {
    fn call(self: Box<Self>);
}

impl<F: FnOnce() + Send + 'static> ExecuteCallback for F {
    fn call(self: Box<F>) {
        (*self)()
    }
}

pub struct Default;

impl Executor for Default {
    fn execute<F: FnOnce() + Send + 'static>(&self, f: F) {
        f()
    }

    fn execute_boxed(&self, f: Box<ExecuteCallback>) {
        f.call()
    }
}

pub struct Limited;

thread_local!(static LIMITED: LimitState = LimitState::new());

const LIMIT: usize = 100;

struct LimitState {
    count: Cell<usize>,
    deferred: RefCell<Vec<Box<ExecuteCallback>>>,
}

impl Executor for Limited {
    fn execute_boxed(&self, f: Box<ExecuteCallback>) {
        LIMITED.with(|state| state.execute(f))
    }
}

impl LimitState {
    fn new() -> LimitState {
        LimitState {
            count: Cell::new(0),
            deferred: RefCell::new(Vec::new()),
        }
    }

    fn execute(&self, cb: Box<ExecuteCallback>) {
        match self.count.get() {
            0 => {
                self.count.set(1);
                let mut cb = Some(cb);
                while let Some(f) = cb {
                    f.call();
                    cb = self.deferred.borrow_mut().pop();
                }
                self.count.set(0);
            }
            n if n < LIMIT => {
                self.count.set(n + 1);
                cb.call();
                self.count.set(n);
            }
            _ => self.deferred.borrow_mut().push(cb),
        }
    }
}

#[cfg(test)]
mod tests {
    use std::sync::Arc;
    use std::sync::atomic::{AtomicUsize, Ordering};

    use super::{Executor, Limited};

    #[test]
    fn limited() {
        fn doit(ex: Arc<Executor>, hits: Arc<AtomicUsize>, i: usize) {
            if i == 0 {
                return
            }
            hits.fetch_add(1, Ordering::SeqCst);
            let ex2 = ex.clone();
            ex.execute(move || {
                doit(ex2, hits, i - 1);
            })
        }

        let n = 1_000_000;
        let hits = Arc::new(AtomicUsize::new(0));
        doit(Arc::new(Limited), hits.clone(), n);
        assert_eq!(hits.load(Ordering::SeqCst), n);
    }
}
<|endoftext|>


<commit_before><commit_msg>added fizzbuzz prog<commit_after>fn main() {
    for i in 1..101 {
        let value = i.to_string();
        println!("{}", match (i % 3, i % 5) {
                         (0,0) => "FizzBuzz",
                         (0,_) => "Fizz",
                         (_,0) => "Buzz",
                          _ => value.as_ref(),
                       });
    }
}<|endoftext|>


<commit_before><commit_msg>Inline call and val for functions<commit_after><|endoftext|>


<commit_before><commit_msg>(refactor) Moved ip, port back to listen as Options.<commit_after><|endoftext|>


<commit_before><commit_msg>Minor adjustment to constants<commit_after><|endoftext|>


<commit_before><commit_msg>Add problem #120<commit_after>#[crate_type = "rlib"];

use std::iter;
use std::iter::AdditiveIterator;

pub static EXPECTED_ANSWER: &'static str = "333082500";

// f(a, n) := (a-1)^n + (a+1)^n
//
// f(a, 1) = 2a
// f(a, 2) = 2(a^2 + 1)
// f(a, 3) = 2(a^3 + 3a)
// f(a, 4) = 2(a^4 + 6a^2 + 1)
// f(a, 5) = 2(a^5 + 10a^3 + 5a)
// f(1, 6) = 2(a^6 + 15a^4 + 15a^2 + 1)
//
// f(a, n) =
//   if n is even:
//     2(a^n + nC2 a^(n-2) + ... + 1)
//   else
//     2(a^n + nC2 a^(n-2) + ... + nC(n-1) a)
//
// f(a, 2k + 1) ≡ 1   mod a^2
// f(a, 2k)     ≡ 4ka mod a^2
//
// => rmax = 2 nmax a < a^2
//    nmax = max[k; k < a/ 2]
//
// nmax =
//   if a is even:
//     (a - 2) / 2
//   else
//     (a - 1) / 2
//
// rmax =
//   if a is even:
//     a (a - 2)
//   else:
//     a (a - 1)

pub fn solve() -> ~str {
    iter::range_inclusive(3, 1000)
        .map(|a| if a.is_even() { a * (a - 2) } else { a * (a - 1) })
        .sum()
        .to_str()
}
<|endoftext|>


<commit_before>import rustrt.sbuf;

import _vec.rustrt.vbuf;

native "rust" mod rustrt {
    type sbuf;
    fn str_buf(str s) -> sbuf;
    fn str_byte_len(str s) -> uint;
    fn str_alloc(uint n_bytes) -> str;
    fn str_from_vec(vec[u8] b) -> str;
    fn str_from_cstr(sbuf cstr) -> str;
    fn str_from_buf(sbuf buf, uint len) -> str;
    fn refcount[T](str s) -> uint;
}

fn eq(&str a, &str b) -> bool {
    let uint i = byte_len(a);
    if (byte_len(b) != i) {
        ret false;
    }
    while (i > 0u) {
        i -= 1u;
        auto cha = a.(i);
        auto chb = b.(i);
        if (cha != chb) {
            ret false;
        }
    }
    ret true;
}

fn lteq(&str a, &str b) -> bool {
    let uint i = byte_len(a);
    let uint j = byte_len(b);
    let uint n = i;
    if (j < n) {
        n = j;
    }

    let uint x = 0u;
    while (x < n) {
        auto cha = a.(x);
        auto chb = b.(x);
        if (cha <= chb) {
            ret true;
        }
        else if (cha > chb) {
            ret false;
        }
        x += 1u;
    }

    ret i <= j;
}

fn hash(&str s) -> uint {
    // djb hash.
    // FIXME: replace with murmur.
    let uint u = 5381u;
    for (u8 c in s) {
        u *= 33u;
        u += (c as uint);
    }
    ret u;
}

fn is_utf8(vec[u8] v) -> bool {
    fail; // FIXME
}

fn is_ascii(str s) -> bool {
    let uint i = byte_len(s);
    while (i > 0u) {
        i -= 1u;
        if ((s.(i) & 0x80u8) != 0u8) {
            ret false;
        }
    }
    ret true;
}

fn alloc(uint n_bytes) -> str {
    ret rustrt.str_alloc(n_bytes);
}

// Returns the number of bytes (a.k.a. UTF-8 code units) in s.
// Contrast with a function that would return the number of code
// points (char's), combining character sequences, words, etc.  See
// http://icu-project.org/apiref/icu4c/classBreakIterator.html for a
// way to implement those.
fn byte_len(str s) -> uint {
    ret rustrt.str_byte_len(s);
}

fn buf(str s) -> sbuf {
    ret rustrt.str_buf(s);
}

fn bytes(str s) -> vec[u8] {
    fn ith(str s, uint i) -> u8 {
        ret s.(i);
    }
    ret _vec.init_fn[u8](bind ith(s, _), byte_len(s));
}

fn from_bytes(vec[u8] v) : is_utf8(v) -> str {
    ret rustrt.str_from_vec(v);
}

// FIXME temp thing
fn unsafe_from_bytes(vec[u8] v) -> str {
    ret rustrt.str_from_vec(v);
}

fn unsafe_from_byte(u8 u) -> str {
    ret rustrt.str_from_vec(vec(u));
}

unsafe fn str_from_cstr(sbuf cstr) -> str {
    ret rustrt.str_from_cstr(cstr);
}

unsafe fn str_from_buf(sbuf buf, uint len) -> str {
    ret rustrt.str_from_buf(buf, len);
}

fn refcount(str s) -> uint {
    auto r = rustrt.refcount[u8](s);
    if (r == dbg.const_refcount) {
        ret r;
    } else {
        // -1 because calling this function incremented the refcount.
        ret  r - 1u;
    }
}

// Standard bits from the world of string libraries.

fn index(str s, u8 c) -> int {
    let int i = 0;
    for (u8 k in s) {
        if (k == c) {
            ret i;
        }
        i += 1;
    }
    ret -1;
}

fn rindex(str s, u8 c) -> int {
    let int n = _str.byte_len(s) as int;
    while (n >= 0) {
        if (s.(n) == c) {
            ret n;
        }
        n -= 1;
    }
    ret n;
}

fn find(str haystack, str needle) -> int {

    let int haystack_len = byte_len(haystack) as int;
    let int needle_len = byte_len(needle) as int;

    if (needle_len == 0) {
        ret 0;
    }

    fn match_at(&str haystack,
                &str needle,
                int i) -> bool {
        let int j = i;
        for (u8 c in needle) {
            if (haystack.(j) != c) {
                ret false;
            }
            j += 1;
        }
        ret true;
    }

    let int i = 0;
    while (i <= haystack_len - needle_len) {
        if (match_at(haystack, needle, i)) {
            ret i;
        }
        i += 1;
    }
    ret  -1;
}

fn starts_with(str haystack, str needle) -> bool {
    let uint haystack_len = byte_len(haystack);
    let uint needle_len = byte_len(needle);
    if (needle_len == 0u) {
        ret true;
    }
    if (needle_len > haystack_len) {
        ret false;
    }
    ret eq(substr(haystack, 0u, needle_len), needle);
}

fn ends_with(str haystack, str needle) -> bool {
    let uint haystack_len = byte_len(haystack);
    let uint needle_len = byte_len(needle);
    if (needle_len == 0u) {
        ret true;
    }
    if (needle_len > haystack_len) {
        ret false;
    }
    ret eq(substr(haystack,
                  haystack_len - needle_len,
                  needle_len),
           needle);
}

fn substr(str s, uint begin, uint len) -> str {
    let str accum = "";
    let uint i = begin;
    while (i < begin+len) {
        accum += unsafe_from_byte(s.(i));
        i += 1u;
    }
    ret accum;
}

fn shift_byte(&mutable str s) -> u8 {
    auto len = byte_len(s);
    check(len > 0u);
    auto b = s.(0);
    s = substr(s, 1u, len - 1u);
    ret b;
}

fn pop_byte(&mutable str s) -> u8 {
    auto len = byte_len(s);
    check(len > 0u);
    auto b = s.(len - 1u);
    s = substr(s, 0u, len - 1u);
    ret b;
}

fn push_byte(&mutable str s, u8 b) {
    s += unsafe_from_byte(b);
}

fn unshift_byte(&mutable str s, u8 b) {
    auto res = alloc(byte_len(s) + 1u);
    res += unsafe_from_byte(b);
    res += s;
    s = res;
}

fn split(str s, u8 sep) -> vec[str] {
    let vec[str] v = vec();
    let str accum = "";
    let bool ends_with_sep = false;
    for (u8 c in s) {
        if (c == sep) {
            v += vec(accum);
            accum = "";
            ends_with_sep = true;
        } else {
            accum += unsafe_from_byte(c);
            ends_with_sep = false;
        }
    }
    if (_str.byte_len(accum) != 0u ||
        ends_with_sep) {
        v += vec(accum);
    }
    ret v;
}

fn concat(vec[str] v) -> str {
    let str s = "";
    for (str ss in v) {
        s += ss;
    }
    ret s;
}

fn connect(vec[str] v, str sep) -> str {
    let str s = "";
    let bool first = true;
    for (str ss in v) {
        if (first) {
            first = false;
        } else {
            s += sep;
        }
        s += ss;
    }
    ret s;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<commit_msg>Fix bug in string comparison. std.rc typechecks now.<commit_after>import rustrt.sbuf;

import _vec.rustrt.vbuf;

native "rust" mod rustrt {
    type sbuf;
    fn str_buf(str s) -> sbuf;
    fn str_byte_len(str s) -> uint;
    fn str_alloc(uint n_bytes) -> str;
    fn str_from_vec(vec[u8] b) -> str;
    fn str_from_cstr(sbuf cstr) -> str;
    fn str_from_buf(sbuf buf, uint len) -> str;
    fn refcount[T](str s) -> uint;
}

fn eq(&str a, &str b) -> bool {
    let uint i = byte_len(a);
    if (byte_len(b) != i) {
        ret false;
    }
    while (i > 0u) {
        i -= 1u;
        auto cha = a.(i);
        auto chb = b.(i);
        if (cha != chb) {
            ret false;
        }
    }
    ret true;
}

fn lteq(&str a, &str b) -> bool {
    let uint i = byte_len(a);
    let uint j = byte_len(b);
    let uint n = i;
    if (j < n) {
        n = j;
    }

    let uint x = 0u;
    while (x < n) {
        auto cha = a.(x);
        auto chb = b.(x);
        if (cha < chb) {
            ret true;
        }
        else if (cha > chb) {
            ret false;
        }
        x += 1u;
    }

    ret i <= j;
}

fn hash(&str s) -> uint {
    // djb hash.
    // FIXME: replace with murmur.
    let uint u = 5381u;
    for (u8 c in s) {
        u *= 33u;
        u += (c as uint);
    }
    ret u;
}

fn is_utf8(vec[u8] v) -> bool {
    fail; // FIXME
}

fn is_ascii(str s) -> bool {
    let uint i = byte_len(s);
    while (i > 0u) {
        i -= 1u;
        if ((s.(i) & 0x80u8) != 0u8) {
            ret false;
        }
    }
    ret true;
}

fn alloc(uint n_bytes) -> str {
    ret rustrt.str_alloc(n_bytes);
}

// Returns the number of bytes (a.k.a. UTF-8 code units) in s.
// Contrast with a function that would return the number of code
// points (char's), combining character sequences, words, etc.  See
// http://icu-project.org/apiref/icu4c/classBreakIterator.html for a
// way to implement those.
fn byte_len(str s) -> uint {
    ret rustrt.str_byte_len(s);
}

fn buf(str s) -> sbuf {
    ret rustrt.str_buf(s);
}

fn bytes(str s) -> vec[u8] {
    fn ith(str s, uint i) -> u8 {
        ret s.(i);
    }
    ret _vec.init_fn[u8](bind ith(s, _), byte_len(s));
}

fn from_bytes(vec[u8] v) : is_utf8(v) -> str {
    ret rustrt.str_from_vec(v);
}

// FIXME temp thing
fn unsafe_from_bytes(vec[u8] v) -> str {
    ret rustrt.str_from_vec(v);
}

fn unsafe_from_byte(u8 u) -> str {
    ret rustrt.str_from_vec(vec(u));
}

unsafe fn str_from_cstr(sbuf cstr) -> str {
    ret rustrt.str_from_cstr(cstr);
}

unsafe fn str_from_buf(sbuf buf, uint len) -> str {
    ret rustrt.str_from_buf(buf, len);
}

fn refcount(str s) -> uint {
    auto r = rustrt.refcount[u8](s);
    if (r == dbg.const_refcount) {
        ret r;
    } else {
        // -1 because calling this function incremented the refcount.
        ret  r - 1u;
    }
}

// Standard bits from the world of string libraries.

fn index(str s, u8 c) -> int {
    let int i = 0;
    for (u8 k in s) {
        if (k == c) {
            ret i;
        }
        i += 1;
    }
    ret -1;
}

fn rindex(str s, u8 c) -> int {
    let int n = _str.byte_len(s) as int;
    while (n >= 0) {
        if (s.(n) == c) {
            ret n;
        }
        n -= 1;
    }
    ret n;
}

fn find(str haystack, str needle) -> int {

    let int haystack_len = byte_len(haystack) as int;
    let int needle_len = byte_len(needle) as int;

    if (needle_len == 0) {
        ret 0;
    }

    fn match_at(&str haystack,
                &str needle,
                int i) -> bool {
        let int j = i;
        for (u8 c in needle) {
            if (haystack.(j) != c) {
                ret false;
            }
            j += 1;
        }
        ret true;
    }

    let int i = 0;
    while (i <= haystack_len - needle_len) {
        if (match_at(haystack, needle, i)) {
            ret i;
        }
        i += 1;
    }
    ret  -1;
}

fn starts_with(str haystack, str needle) -> bool {
    let uint haystack_len = byte_len(haystack);
    let uint needle_len = byte_len(needle);
    if (needle_len == 0u) {
        ret true;
    }
    if (needle_len > haystack_len) {
        ret false;
    }
    ret eq(substr(haystack, 0u, needle_len), needle);
}

fn ends_with(str haystack, str needle) -> bool {
    let uint haystack_len = byte_len(haystack);
    let uint needle_len = byte_len(needle);
    if (needle_len == 0u) {
        ret true;
    }
    if (needle_len > haystack_len) {
        ret false;
    }
    ret eq(substr(haystack,
                  haystack_len - needle_len,
                  needle_len),
           needle);
}

fn substr(str s, uint begin, uint len) -> str {
    let str accum = "";
    let uint i = begin;
    while (i < begin+len) {
        accum += unsafe_from_byte(s.(i));
        i += 1u;
    }
    ret accum;
}

fn shift_byte(&mutable str s) -> u8 {
    auto len = byte_len(s);
    check(len > 0u);
    auto b = s.(0);
    s = substr(s, 1u, len - 1u);
    ret b;
}

fn pop_byte(&mutable str s) -> u8 {
    auto len = byte_len(s);
    check(len > 0u);
    auto b = s.(len - 1u);
    s = substr(s, 0u, len - 1u);
    ret b;
}

fn push_byte(&mutable str s, u8 b) {
    s += unsafe_from_byte(b);
}

fn unshift_byte(&mutable str s, u8 b) {
    auto res = alloc(byte_len(s) + 1u);
    res += unsafe_from_byte(b);
    res += s;
    s = res;
}

fn split(str s, u8 sep) -> vec[str] {
    let vec[str] v = vec();
    let str accum = "";
    let bool ends_with_sep = false;
    for (u8 c in s) {
        if (c == sep) {
            v += vec(accum);
            accum = "";
            ends_with_sep = true;
        } else {
            accum += unsafe_from_byte(c);
            ends_with_sep = false;
        }
    }
    if (_str.byte_len(accum) != 0u ||
        ends_with_sep) {
        v += vec(accum);
    }
    ret v;
}

fn concat(vec[str] v) -> str {
    let str s = "";
    for (str ss in v) {
        s += ss;
    }
    ret s;
}

fn connect(vec[str] v, str sep) -> str {
    let str s = "";
    let bool first = true;
    for (str ss in v) {
        if (first) {
            first = false;
        } else {
            s += sep;
        }
        s += ss;
    }
    ret s;
}

// Local Variables:
// mode: rust;
// fill-column: 78;
// indent-tabs-mode: nil
// c-basic-offset: 4
// buffer-file-coding-system: utf-8-unix
// compile-command: "make -k -C .. 2>&1 | sed -e 's/\\/x\\//x:\\//g'";
// End:
<|endoftext|>


<commit_before>// Interior vector utility functions.

import option::none;
import option::some;
import uint::next_power_of_two;
import ptr::addr_of;

type operator2[T,U,V] = fn(&T, &U) -> V;

native "rust-intrinsic" mod rusti {
    fn ivec_len[T](&T[] v) -> uint;
}

native "rust" mod rustrt {
    fn ivec_reserve_shared[T](&mutable T[mutable?] v, uint n);
    fn ivec_on_heap[T](&T[] v) -> uint;
    fn ivec_to_ptr[T](&T[] v) -> *T;
    fn ivec_copy_from_buf_shared[T](&mutable T[mutable?] v,
                                    *T ptr, uint count);
}

/// Reserves space for `n` elements in the given vector.
fn reserve[T](&mutable T[mutable?] v, uint n) {
    rustrt::ivec_reserve_shared(v, n);
}

fn on_heap[T](&T[] v) -> bool {
    ret rustrt::ivec_on_heap(v) != 0u;
}

fn to_ptr[T](&T[] v) -> *T {
    ret rustrt::ivec_to_ptr(v);
}

fn len[T](&T[mutable?] v) -> uint {
    ret rusti::ivec_len(v);
}

type init_op[T] = fn(uint) -> T;

fn init_fn[T](&init_op[T] op, uint n_elts) -> T[] {
    auto v = ~[];
    reserve(v, n_elts);
    let uint i = 0u;
    while (i < n_elts) { v += ~[op(i)]; i += 1u; }
    ret v;
}

// TODO: Remove me once we have slots.
fn init_fn_mut[T](&init_op[T] op, uint n_elts) -> T[mutable] {
    auto v = ~[mutable];
    reserve(v, n_elts);
    let uint i = 0u;
    while (i < n_elts) { v += ~[mutable op(i)]; i += 1u; }
    ret v;
}

fn init_elt[T](&T t, uint n_elts) -> T[] {
    auto v = ~[];
    reserve(v, n_elts);
    let uint i = 0u;
    while (i < n_elts) { v += ~[t]; i += 1u; }
    ret v;
}

// TODO: Remove me once we have slots.
fn init_elt_mut[T](&T t, uint n_elts) -> T[mutable] {
    auto v = ~[mutable];
    reserve(v, n_elts);
    let uint i = 0u;
    while (i < n_elts) { v += ~[mutable t]; i += 1u; }
    ret v;
}

// Accessors

/// Returns the last element of `v`.
fn last[T](&T[mutable?] v) -> option::t[T] {
    if (len(v) == 0u) { ret none; }
    ret some(v.(len(v) - 1u));
}

/// Returns a copy of the elements from [`start`..`end`) from `v`.
fn slice[T](&T[mutable?] v, uint start, uint end) -> T[] {
    assert (start <= end);
    assert (end <= len(v));
    auto result = ~[];
    reserve(result, end - start);
    auto i = start;
    while (i < end) { result += ~[v.(i)]; i += 1u; }
    ret result;
}

// TODO: Remove me once we have slots.
fn slice_mut[T](&T[mutable?] v, uint start, uint end) -> T[mutable] {
    assert (start <= end);
    assert (end <= len(v));
    auto result = ~[mutable];
    reserve(result, end - start);
    auto i = start;
    while (i < end) { result += ~[mutable v.(i)]; i += 1u; }
    ret result;
}

// Mutators

// TODO: Write this, unsafely, in a way that's not O(n).
fn pop[T](&mutable T[mutable?] v) -> T {
    auto ln = len(v);
    assert (ln > 0u);
    ln -= 1u;
    auto e = v.(ln);
    v = slice(v, 0u, ln);
    ret e;
}

// TODO: More.

// Appending

/// Expands the given vector in-place by appending `n` copies of `initval`.
fn grow[T](&mutable T[] v, uint n, &T initval) {
    reserve(v, next_power_of_two(len(v) + n));
    let uint i = 0u;
    while (i < n) {
        v += ~[initval];
        i += 1u;
    }
}

// TODO: Remove me once we have slots.
fn grow_mut[T](&mutable T[mutable] v, uint n, &T initval) {
    reserve(v, next_power_of_two(len(v) + n));
    let uint i = 0u;
    while (i < n) {
        v += ~[mutable initval];
        i += 1u;
    }
}

/// Calls `f` `n` times and appends the results of these calls to the given
/// vector.
fn grow_fn[T](&mutable T[] v, uint n, fn(uint)->T init_fn) {
    reserve(v, next_power_of_two(len(v) + n));
    let uint i = 0u;
    while (i < n) {
        v += ~[init_fn(i)];
        i += 1u;
    }
}

/// Sets the element at position `index` to `val`. If `index` is past the end
/// of the vector, expands the vector by replicating `initval` to fill the
/// intervening space.
fn grow_set[T](&mutable T[mutable] v, uint index, &T initval, &T val) {
    if (index >= len(v)) { grow_mut(v, index - len(v) + 1u, initval); }
    v.(index) = val;
}

// Functional utilities

fn map[T,U](fn(&T)->U f, &T[mutable?] v) -> U[] {
    auto result = ~[];
    reserve(result, len(v));
    for (T elem in v) {
        auto elem2 = elem;  // satisfies alias checker
        result += ~[f(elem2)];
    }
    ret result;
}

fn filter_map[T,U](fn(&T)->option::t[U] f, &T[mutable?] v) -> U[] {
    auto result = ~[];
    for (T elem in v) {
        auto elem2 = elem;  // satisfies alias checker
        alt (f(elem2)) {
          case (none) { /* no-op */ }
          case (some(?result_elem)) { result += ~[result_elem]; }
        }
    }
    ret result;
}

fn foldl[T,U](fn(&U,&T)->U p, &U z, &T[mutable?] v) -> U {
    auto sz = len(v);
    if (sz == 0u) { ret z; }
    auto first = v.(0);
    auto rest = slice(v, 1u, sz);
    ret p(foldl[T,U](p, z, rest), first);
}

fn any[T](fn(&T)->bool f, &T[] v) -> bool {
    for (T elem in v) { if (f(elem)) { ret true; } }
    ret false;
}

fn all[T](fn(&T)->bool f, &T[] v) -> bool {
    for (T elem in v) { if (!f(elem)) { ret false; } }
    ret true;
}

fn member[T](&T x, &T[] v) -> bool {
    for (T elt in v) { if (x == elt) { ret true; } }
    ret false;
}

fn find[T](fn(&T) -> bool  f, &T[] v) -> option::t[T] {
    for (T elt in v) { if (f(elt)) { ret some[T](elt); } }
    ret none[T];
}

mod unsafe {
    type ivec_repr = rec(mutable uint fill,
                         mutable uint alloc,
                         *mutable ivec_heap_part heap_part);
    type ivec_heap_part = rec(mutable uint fill);

    fn copy_from_buf[T](&mutable T[] v, *T ptr, uint count) {
        ret rustrt::ivec_copy_from_buf_shared(v, ptr, count);
    }

    fn from_buf[T](*T ptr, uint bytes) -> T[] {
        auto v = ~[];
        copy_from_buf(v, ptr, bytes);
        ret v;
    }

    fn set_len[T](&mutable T[] v, uint new_len) {
        auto new_fill = new_len * sys::size_of[T]();
        let *mutable ivec_repr stack_part =
            ::unsafe::reinterpret_cast(addr_of(v));
        if ((*stack_part).fill == 0u) {
            (*(*stack_part).heap_part).fill = new_fill;     // On heap.
        } else {
            (*stack_part).fill = new_fill;                  // On stack.
        }
    }
}

<commit_msg>stdlib: Implement ivec::count<commit_after>// Interior vector utility functions.

import option::none;
import option::some;
import uint::next_power_of_two;
import ptr::addr_of;

type operator2[T,U,V] = fn(&T, &U) -> V;

native "rust-intrinsic" mod rusti {
    fn ivec_len[T](&T[] v) -> uint;
}

native "rust" mod rustrt {
    fn ivec_reserve_shared[T](&mutable T[mutable?] v, uint n);
    fn ivec_on_heap[T](&T[] v) -> uint;
    fn ivec_to_ptr[T](&T[] v) -> *T;
    fn ivec_copy_from_buf_shared[T](&mutable T[mutable?] v,
                                    *T ptr, uint count);
}

/// Reserves space for `n` elements in the given vector.
fn reserve[T](&mutable T[mutable?] v, uint n) {
    rustrt::ivec_reserve_shared(v, n);
}

fn on_heap[T](&T[] v) -> bool {
    ret rustrt::ivec_on_heap(v) != 0u;
}

fn to_ptr[T](&T[] v) -> *T {
    ret rustrt::ivec_to_ptr(v);
}

fn len[T](&T[mutable?] v) -> uint {
    ret rusti::ivec_len(v);
}

type init_op[T] = fn(uint) -> T;

fn init_fn[T](&init_op[T] op, uint n_elts) -> T[] {
    auto v = ~[];
    reserve(v, n_elts);
    let uint i = 0u;
    while (i < n_elts) { v += ~[op(i)]; i += 1u; }
    ret v;
}

// TODO: Remove me once we have slots.
fn init_fn_mut[T](&init_op[T] op, uint n_elts) -> T[mutable] {
    auto v = ~[mutable];
    reserve(v, n_elts);
    let uint i = 0u;
    while (i < n_elts) { v += ~[mutable op(i)]; i += 1u; }
    ret v;
}

fn init_elt[T](&T t, uint n_elts) -> T[] {
    auto v = ~[];
    reserve(v, n_elts);
    let uint i = 0u;
    while (i < n_elts) { v += ~[t]; i += 1u; }
    ret v;
}

// TODO: Remove me once we have slots.
fn init_elt_mut[T](&T t, uint n_elts) -> T[mutable] {
    auto v = ~[mutable];
    reserve(v, n_elts);
    let uint i = 0u;
    while (i < n_elts) { v += ~[mutable t]; i += 1u; }
    ret v;
}

// Accessors

/// Returns the last element of `v`.
fn last[T](&T[mutable?] v) -> option::t[T] {
    if (len(v) == 0u) { ret none; }
    ret some(v.(len(v) - 1u));
}

/// Returns a copy of the elements from [`start`..`end`) from `v`.
fn slice[T](&T[mutable?] v, uint start, uint end) -> T[] {
    assert (start <= end);
    assert (end <= len(v));
    auto result = ~[];
    reserve(result, end - start);
    auto i = start;
    while (i < end) { result += ~[v.(i)]; i += 1u; }
    ret result;
}

// TODO: Remove me once we have slots.
fn slice_mut[T](&T[mutable?] v, uint start, uint end) -> T[mutable] {
    assert (start <= end);
    assert (end <= len(v));
    auto result = ~[mutable];
    reserve(result, end - start);
    auto i = start;
    while (i < end) { result += ~[mutable v.(i)]; i += 1u; }
    ret result;
}

// Mutators

// TODO: Write this, unsafely, in a way that's not O(n).
fn pop[T](&mutable T[mutable?] v) -> T {
    auto ln = len(v);
    assert (ln > 0u);
    ln -= 1u;
    auto e = v.(ln);
    v = slice(v, 0u, ln);
    ret e;
}

// TODO: More.

// Appending

/// Expands the given vector in-place by appending `n` copies of `initval`.
fn grow[T](&mutable T[] v, uint n, &T initval) {
    reserve(v, next_power_of_two(len(v) + n));
    let uint i = 0u;
    while (i < n) {
        v += ~[initval];
        i += 1u;
    }
}

// TODO: Remove me once we have slots.
fn grow_mut[T](&mutable T[mutable] v, uint n, &T initval) {
    reserve(v, next_power_of_two(len(v) + n));
    let uint i = 0u;
    while (i < n) {
        v += ~[mutable initval];
        i += 1u;
    }
}

/// Calls `f` `n` times and appends the results of these calls to the given
/// vector.
fn grow_fn[T](&mutable T[] v, uint n, fn(uint)->T init_fn) {
    reserve(v, next_power_of_two(len(v) + n));
    let uint i = 0u;
    while (i < n) {
        v += ~[init_fn(i)];
        i += 1u;
    }
}

/// Sets the element at position `index` to `val`. If `index` is past the end
/// of the vector, expands the vector by replicating `initval` to fill the
/// intervening space.
fn grow_set[T](&mutable T[mutable] v, uint index, &T initval, &T val) {
    if (index >= len(v)) { grow_mut(v, index - len(v) + 1u, initval); }
    v.(index) = val;
}

// Functional utilities

fn map[T,U](fn(&T)->U f, &T[mutable?] v) -> U[] {
    auto result = ~[];
    reserve(result, len(v));
    for (T elem in v) {
        auto elem2 = elem;  // satisfies alias checker
        result += ~[f(elem2)];
    }
    ret result;
}

fn filter_map[T,U](fn(&T)->option::t[U] f, &T[mutable?] v) -> U[] {
    auto result = ~[];
    for (T elem in v) {
        auto elem2 = elem;  // satisfies alias checker
        alt (f(elem2)) {
          case (none) { /* no-op */ }
          case (some(?result_elem)) { result += ~[result_elem]; }
        }
    }
    ret result;
}

fn foldl[T,U](fn(&U,&T)->U p, &U z, &T[mutable?] v) -> U {
    auto sz = len(v);
    if (sz == 0u) { ret z; }
    auto first = v.(0);
    auto rest = slice(v, 1u, sz);
    ret p(foldl[T,U](p, z, rest), first);
}

fn any[T](fn(&T)->bool f, &T[] v) -> bool {
    for (T elem in v) { if (f(elem)) { ret true; } }
    ret false;
}

fn all[T](fn(&T)->bool f, &T[] v) -> bool {
    for (T elem in v) { if (!f(elem)) { ret false; } }
    ret true;
}

fn member[T](&T x, &T[] v) -> bool {
    for (T elt in v) { if (x == elt) { ret true; } }
    ret false;
}

fn count[T](&T x, &T[mutable?] v) -> uint {
    auto cnt = 0u;
    for (T elt in v) { if (x == elt) { cnt += 1u; } }
    ret cnt;
}

fn find[T](fn(&T) -> bool  f, &T[] v) -> option::t[T] {
    for (T elt in v) { if (f(elt)) { ret some[T](elt); } }
    ret none[T];
}

mod unsafe {
    type ivec_repr = rec(mutable uint fill,
                         mutable uint alloc,
                         *mutable ivec_heap_part heap_part);
    type ivec_heap_part = rec(mutable uint fill);

    fn copy_from_buf[T](&mutable T[] v, *T ptr, uint count) {
        ret rustrt::ivec_copy_from_buf_shared(v, ptr, count);
    }

    fn from_buf[T](*T ptr, uint bytes) -> T[] {
        auto v = ~[];
        copy_from_buf(v, ptr, bytes);
        ret v;
    }

    fn set_len[T](&mutable T[] v, uint new_len) {
        auto new_fill = new_len * sys::size_of[T]();
        let *mutable ivec_repr stack_part =
            ::unsafe::reinterpret_cast(addr_of(v));
        if ((*stack_part).fill == 0u) {
            (*(*stack_part).heap_part).fill = new_fill;     // On heap.
        } else {
            (*stack_part).fill = new_fill;                  // On stack.
        }
    }
}

<|endoftext|>


<commit_before><commit_msg>Add Bold text formatting<commit_after><|endoftext|>


<commit_before>// 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.

use std::fmt;
use std::io;

#[deriving(Clone)]
pub struct Layout {
    logo: ~str,
    favicon: ~str,
    krate: ~str,
}

pub struct Page<'a> {
    title: &'a str,
    ty: &'a str,
    root_path: &'a str,
}

pub fn render<T: fmt::Show, S: fmt::Show>(
    dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
    -> fmt::Result
{
    write!(dst,
"<!DOCTYPE html>

    <meta charset=\"utf-8\" />
    <title>{title}</title>

    <link href='http://fonts.googleapis.com/css?family=Oswald:700|Inconsolata:400,700'
          rel='stylesheet' type='text/css'>
    <link rel=\"stylesheet\" type=\"text/css\" href=\"{root_path}main.css\">

    {favicon, select, none{} other{<link rel=\"shortcut icon\" href=\"#\" />}}

        {logo, select, none{} other{

        }}

        {sidebar}

        <form class=\"search-form js-only\">
            <button class=\"do-search\">Search</button>

                <input class=\"search-input\" name=\"search\"
                       autocomplete=\"off\"
                       placeholder=\"Search documentation...\"
                       type=\"search\" />

        </form>

{content}

Keyboard shortcuts

?

Show this help dialog

S

Focus the search field

↑

Move up in search results

↓

Move down in search results

&\\#9166;

Go to active search result

Search tricks

                Prefix searches with a type followed by a colon (e.g.
                fn:) to restrict the search to a given type.

                Accepted types are: fn, mod,
                struct (or str), enum,
                trait, typedef (or
                tdef).

",
    content   = *t,
    root_path = page.root_path,
    ty        = page.ty,
    logo      = nonestr(layout.logo),
    title     = page.title,
    favicon   = nonestr(layout.favicon),
    sidebar   = *sidebar,
    krate     = layout.krate,
    )
}

fn nonestr<'a>(s: &'a str) -> &'a str {
    if s == "" { "none" } else { s }
}
<commit_msg>rustdoc: html: use raw strings for great justice<commit_after>// 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.

use std::fmt;
use std::io;

#[deriving(Clone)]
pub struct Layout {
    logo: ~str,
    favicon: ~str,
    krate: ~str,
}

pub struct Page<'a> {
    title: &'a str,
    ty: &'a str,
    root_path: &'a str,
}

pub fn render<T: fmt::Show, S: fmt::Show>(
    dst: &mut io::Writer, layout: &Layout, page: &Page, sidebar: &S, t: &T)
    -> fmt::Result
{
    write!(dst,
r##"<!DOCTYPE html>

    <meta charset="utf-8" />
    <title>{title}</title>

    <link href='http://fonts.googleapis.com/css?family=Oswald:700|Inconsolata:400,700'
          rel='stylesheet' type='text/css'>
    <link rel="stylesheet" type="text/css" href="{root_path}main.css">

    {favicon, select, none{} other{<link rel="shortcut icon" href="\#" />}}

        {logo, select, none{} other{

        }}

        {sidebar}

        <form class="search-form js-only">
            <button class="do-search">Search</button>

                <input class="search-input" name="search"
                       autocomplete="off"
                       placeholder="Search documentation..."
                       type="search" />

        </form>

{content}

Keyboard shortcuts

?

Show this help dialog

S

Focus the search field

↑

Move up in search results

↓

Move down in search results

&\#9166;

Go to active search result

Search tricks

                Prefix searches with a type followed by a colon (e.g.
                fn:) to restrict the search to a given type.

                Accepted types are: fn, mod,
                struct (or str), enum,
                trait, typedef (or
                tdef).

"##,
    content   = *t,
    root_path = page.root_path,
    ty        = page.ty,
    logo      = nonestr(layout.logo),
    title     = page.title,
    favicon   = nonestr(layout.favicon),
    sidebar   = *sidebar,
    krate     = layout.krate,
    )
}

fn nonestr<'a>(s: &'a str) -> &'a str {
    if s == "" { "none" } else { s }
}
<|endoftext|>


<commit_before>// Copyright 2012-2015 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.

use hir::def_id::DefId;
use super::DepNode;
use super::thread::{DepGraphThreadData, DepMessage};

pub struct DepTask<'graph> {
    data: &'graph DepGraphThreadData,
    key: DepNode<DefId>,
}

impl<'graph> DepTask<'graph> {
    pub fn new(data: &'graph DepGraphThreadData, key: DepNode<DefId>)
               -> DepTask<'graph> {
        data.enqueue(DepMessage::PushTask(key.clone()));
        DepTask { data: data, key: key }
    }
}

impl<'graph> Drop for DepTask<'graph> {
    fn drop(&mut self) {
        self.data.enqueue(DepMessage::PopTask(self.key.clone()));
    }
}

pub struct IgnoreTask<'graph> {
    data: &'graph DepGraphThreadData
}

impl<'graph> IgnoreTask<'graph> {
    pub fn new(data: &'graph DepGraphThreadData) -> IgnoreTask<'graph> {
        data.enqueue(DepMessage::PushIgnore);
        IgnoreTask { data: data }
    }
}

impl<'graph> Drop for IgnoreTask<'graph> {
    fn drop(&mut self) {
        self.data.enqueue(DepMessage::PopIgnore);
    }
}
<commit_msg>avoid extra clone<commit_after>// Copyright 2012-2015 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.

use hir::def_id::DefId;
use super::DepNode;
use super::thread::{DepGraphThreadData, DepMessage};

pub struct DepTask<'graph> {
    data: &'graph DepGraphThreadData,
    key: Option<DepNode<DefId>>,
}

impl<'graph> DepTask<'graph> {
    pub fn new(data: &'graph DepGraphThreadData, key: DepNode<DefId>)
               -> DepTask<'graph> {
        data.enqueue(DepMessage::PushTask(key.clone()));
        DepTask { data: data, key: Some(key) }
    }
}

impl<'graph> Drop for DepTask<'graph> {
    fn drop(&mut self) {
        self.data.enqueue(DepMessage::PopTask(self.key.take().unwrap()));
    }
}

pub struct IgnoreTask<'graph> {
    data: &'graph DepGraphThreadData
}

impl<'graph> IgnoreTask<'graph> {
    pub fn new(data: &'graph DepGraphThreadData) -> IgnoreTask<'graph> {
        data.enqueue(DepMessage::PushIgnore);
        IgnoreTask { data: data }
    }
}

impl<'graph> Drop for IgnoreTask<'graph> {
    fn drop(&mut self) {
        self.data.enqueue(DepMessage::PopIgnore);
    }
}
<|endoftext|>