Reformat a bunch of recent churn.

This commit is contained in:
Graydon Hoare 2011-06-16 16:55:46 -07:00
parent eb9969f546
commit b84fffaa4e
26 changed files with 471 additions and 470 deletions

View File

@ -90,9 +90,10 @@ const int obj_body_elt_fields = 2;
const int obj_body_elt_with_obj = 3;
/* The base object to which an anonymous
* object is attached */
const int fn_field_code = 0;
/* The base object to which an anonymous
* object is attached */
const int fn_field_code = 0;
const int fn_field_box = 1;

View File

@ -175,6 +175,7 @@ mod write {
} else {
// If we aren't saving temps then just output the file
// type corresponding to the '-c' or '-S' flag used
auto triple = x86::get_target_triple();
llvm::LLVMRustWriteOutputFile(pm.llpm, llmod,
str::buf(triple),

View File

@ -16,11 +16,9 @@ fn get_meta_sect_name() -> str {
fn get_data_layout() -> str {
if (str::eq(target_os(), "macos")) {
ret "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16"
+ "-i32:32:32-i64:32:64"
+ "-f32:32:32-f64:32:64-v64:64:64"
+ "-v128:128:128-a0:0:64-f80:128:128"
+ "-n8:16:32";
ret "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16" + "-i32:32:32-i64:32:64" +
"-f32:32:32-f64:32:64-v64:64:64" +
"-v128:128:128-a0:0:64-f80:128:128" + "-n8:16:32";
}
if (str::eq(target_os(), "win32")) {
ret "e-p:32:32-f64:64:64-i64:64:64-f80:32:32-n8:16:32";

View File

@ -239,7 +239,7 @@ fn build_session_options(str binary, getopts::match match) ->
case ("3") { 3u }
case (_) {
log_err "error: optimization level needs " +
"to be between 0-3";
"to be between 0-3";
fail
}
}
@ -399,13 +399,11 @@ fn main(vec[str] args) {
let str prog = "gcc";
// The invocations of gcc share some flags across platforms
let vec[str] common_args = [stage, "-Lrt", "-lrustrt",
"-fno-strict-aliasing", "-fPIC", "-Wall",
"-fno-rtti", "-fno-exceptions", "-g", glu, "-o",
saved_out_filename, saved_out_filename + ".o"];
auto shared_cmd;
let vec[str] common_args =
[stage, "-Lrt", "-lrustrt", "-fno-strict-aliasing", "-fPIC",
"-Wall", "-fno-rtti", "-fno-exceptions", "-g", glu, "-o",
saved_out_filename, saved_out_filename + ".o"];
auto shared_cmd;
alt (sess.get_targ_cfg().os) {
case (session::os_win32) {
shared_cmd = "-shared";
@ -421,12 +419,12 @@ fn main(vec[str] args) {
}
}
if (sopts.shared) {
gcc_args += [shared_cmd];
gcc_args += [shared_cmd];
} else {
gcc_args += ["-Lrustllvm", "-lrustllvm", "-lstd", "-lm", main];
gcc_args += ["-Lrustllvm", "-lrustllvm", "-lstd", "-lm", main];
}
// We run 'gcc' here
run::run_program(prog, gcc_args);
// Clean up on Darwin

View File

@ -245,13 +245,16 @@ tag expr_ {
expr_alt(@expr, vec[arm], ann);
expr_fn(_fn, ann);
expr_block(block, ann);
expr_move(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_assign(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_swap(@expr /* TODO: @expr|is_lval */,
@expr /* TODO: @expr|is_lval */, ann);
expr_assign_op(binop, @expr /* TODO: @expr|is_lval */, @expr, ann);
expr_send(@expr /* TODO: @expr|is_lval */, @expr, ann);
expr_recv(@expr /* TODO: @expr|is_lval */, @expr, ann);
/*
* FIXME: many of these @exprs should be constrained with
* is_lval once we have constrained types working.
*/
expr_move(@expr, @expr, ann);
expr_assign(@expr,@expr, ann);
expr_swap(@expr, @expr, ann);
expr_assign_op(binop, @expr, @expr, ann);
expr_send(@expr, @expr, ann);
expr_recv(@expr, @expr, ann);
expr_field(@expr, ident, ann);
expr_index(@expr, @expr, ann);
expr_path(path, ann);
@ -366,16 +369,14 @@ type constr_arg = constr_arg_general[uint];
type constr_arg_general[T] = spanned[constr_arg_general_[T]];
type constr_ = rec(path path,
vec[@constr_arg_general[uint]] args,
ann ann);
type constr_ = rec(path path, vec[@constr_arg_general[uint]] args, ann ann);
type constr = spanned[constr_];
/* The parser generates ast::constrs; resolve generates
a mapping from each function to a list of ty::constr_defs,
corresponding to these. */
type arg = rec(mode mode, @ty ty, ident ident, def_id id);
type fn_decl =
@ -464,12 +465,14 @@ tag attr_style { attr_outer; attr_inner; }
type attribute_ = rec(attr_style style, meta_item value);
type item = rec(ident ident,
vec[attribute] attrs,
def_id id, // For objs, this is the type def_id
ann ann,
item_ node,
span span);
type item =
rec(ident ident,
vec[attribute] attrs,
def_id id, // For objs, this is the type def_id
ann ann,
item_ node,
span span);
tag item_ {
item_const(@ty, @expr);
@ -478,7 +481,9 @@ tag item_ {
item_native_mod(native_mod);
item_ty(@ty, vec[ty_param]);
item_tag(vec[variant], vec[ty_param]);
item_obj(_obj, vec[ty_param], def_id /* constructor id */);
item_obj(_obj, vec[ty_param], def_id);
/* constructor id */
}
type native_item = spanned[native_item_];
@ -521,9 +526,9 @@ fn is_exported(ident i, _mod m) -> bool {
case (_) {/* fall through */ }
}
}
// If there are no declared exports then
// everything not imported is exported
ret count == 0u && !nonlocal;
}

View File

@ -478,8 +478,7 @@ fn tag_variant_ids(&ebml::doc item, int this_cnum) -> vec[ast::def_id] {
fn get_metadata_section(str filename) -> option::t[vec[u8]] {
auto b = str::buf(filename);
auto mb =
llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(b);
auto mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(b);
if (mb as int == 0) { ret option::none[vec[u8]]; }
auto of = mk_object_file(mb);
auto si = mk_section_iter(of.llof);

View File

@ -294,8 +294,9 @@ fn eval_crate_directive(ctx cx, env e, @ast::crate_directive cdir, str prefix,
cx.p.set_def(next_id._1);
cx.chpos = p0.get_chpos();
cx.next_ann = p0.next_ann_num();
auto i = front::parser::mk_item(cx.p, cdir.span.lo, cdir.span.hi,
id, ast::item_mod(m0), []);
auto i =
front::parser::mk_item(cx.p, cdir.span.lo, cdir.span.hi, id,
ast::item_mod(m0), []);
vec::push[@ast::item](items, i);
}
case (ast::cdir_dir_mod(?id, ?dir_opt, ?cdirs)) {
@ -303,8 +304,9 @@ fn eval_crate_directive(ctx cx, env e, @ast::crate_directive cdir, str prefix,
alt (dir_opt) { case (some(?d)) { path = d; } case (none) { } }
auto full_path = prefix + std::fs::path_sep() + path;
auto m0 = eval_crate_directives_to_mod(cx, e, cdirs, full_path);
auto i = front::parser::mk_item
(cx.p, cdir.span.lo, cdir.span.hi, id, ast::item_mod(m0), []);
auto i =
front::parser::mk_item(cx.p, cdir.span.lo, cdir.span.hi, id,
ast::item_mod(m0), []);
vec::push[@ast::item](items, i);
}
case (ast::cdir_view_item(?vi)) {

View File

@ -281,7 +281,7 @@ fn scan_number(char c, &reader rdr) -> token::token {
rdr.bump();
ret token::LIT_MACH_FLOAT(util::common::ty_f64,
intern(*rdr.get_interner(),
float_str));
float_str));
/* FIXME: if this is out of range for either a 32-bit or
64-bit float, it won't be noticed till the back-end */

View File

@ -34,12 +34,12 @@ type scope = vec[restrict];
tag local_info { arg(ast::mode); objfield(ast::mutability); }
type ctx =
rec(@ty::ctxt tcx,
std::map::hashmap[def_num, local_info] local_map);
rec(@ty::ctxt tcx, std::map::hashmap[def_num, local_info] local_map);
fn check_crate(@ty::ctxt tcx, &@ast::crate crate) {
auto cx =
@rec(tcx=tcx,
// Stores information about object fields and function
// arguments that's otherwise not easily available.
local_map=util::common::new_int_hash());
@ -93,8 +93,8 @@ fn visit_expr(@ctx cx, &@ast::expr ex, &scope sc, &vt[scope] v) {
auto root = expr_root(*cx, ex, false);
if (mut_field(root.ds)) {
cx.tcx.sess.span_err(ex.span,
"result of put must be"
+ " immutably rooted");
"result of put must be" +
" immutably rooted");
}
visit_expr(cx, ex, sc, v);
}
@ -129,7 +129,6 @@ fn check_call(&ctx cx, &@ast::expr f, &vec[@ast::expr] args, &scope sc) ->
rec(vec[def_num] root_vars, vec[ty::t] unsafe_ts) {
auto fty = ty::expr_ty(*cx.tcx, f);
auto arg_ts = fty_args(cx, fty);
let vec[def_num] roots = [];
let vec[tup(uint, def_num)] mut_roots = [];
let vec[ty::t] unsafe_ts = [];
@ -146,7 +145,8 @@ fn check_call(&ctx cx, &@ast::expr f, &vec[@ast::expr] args, &scope sc) ->
}
case (_) {
if (!mut_field(root.ds)) {
auto m = "passing a temporary value or \
auto m =
"passing a temporary value or \
immutable field by mutable alias";
cx.tcx.sess.span_err(arg.span, m);
}
@ -171,10 +171,10 @@ fn check_call(&ctx cx, &@ast::expr f, &vec[@ast::expr] args, &scope sc) ->
alt (f.node) {
case (ast::expr_path(_, ?ann)) {
if (def_is_local(cx.tcx.def_map.get(ann.id), true)) {
cx.tcx.sess.span_err
(f.span, #fmt("function may alias with argument \
%u, which is not immutably rooted",
unsafe_t_offsets.(0)));
cx.tcx.sess.span_err(f.span,
#fmt("function may alias with \
argument %u, which is not immutably rooted",
unsafe_t_offsets.(0)));
}
}
case (_) { }
@ -218,9 +218,10 @@ fn check_call(&ctx cx, &@ast::expr f, &vec[@ast::expr] args, &scope sc) ->
fn check_tail_call(&ctx cx, &@ast::expr call) {
auto args;
auto f = alt (call.node) {
case (ast::expr_call(?f, ?args_, _)) { args = args_; f }
};
auto f =
alt (call.node) {
case (ast::expr_call(?f, ?args_, _)) { args = args_; f }
};
auto i = 0u;
for (ty::arg arg_t in fty_args(cx, ty::expr_ty(*cx.tcx, f))) {
if (arg_t.mode != ty::mo_val) {
@ -233,30 +234,28 @@ fn check_tail_call(&ctx cx, &@ast::expr call) {
alt (cx.local_map.find(dnum)) {
case (some(arg(ast::alias(?mut)))) {
if (mut_a && !mut) {
cx.tcx.sess.span_warn
(args.(i).span, "passing an immutable \
cx.tcx.sess.span_warn(args.(i).span,
"passing an immutable \
alias by mutable alias");
}
}
case (_) {
ok = !def_is_local(def, false);
}
case (_) { ok = !def_is_local(def, false); }
}
}
case (_) { ok = false; }
}
if (!ok) {
cx.tcx.sess.span_warn
(args.(i).span, "can not pass a local value by alias to \
a tail call");
cx.tcx.sess.span_warn(args.(i).span,
"can not pass a local value by \
alias to a tail call");
}
}
i += 1u;
}
}
fn check_alt(&ctx cx, &@ast::expr input, &vec[ast::arm] arms,
&scope sc, &vt[scope] v) {
fn check_alt(&ctx cx, &@ast::expr input, &vec[ast::arm] arms, &scope sc,
&vt[scope] v) {
visit::visit_expr(input, sc, v);
auto root = expr_root(cx, input, true);
auto roots =
@ -630,21 +629,20 @@ fn ty_can_unsafely_include(&ctx cx, ty::t needle, ty::t haystack, bool mut) ->
fn def_is_local(&ast::def d, bool objfields_count) -> bool {
ret alt (d) {
case (ast::def_local(_)) { true }
case (ast::def_arg(_)) { true }
case (ast::def_obj_field(_)) { objfields_count }
case (ast::def_binding(_)) { true }
case (_) { false }
};
case (ast::def_local(_)) { true }
case (ast::def_arg(_)) { true }
case (ast::def_obj_field(_)) { objfields_count }
case (ast::def_binding(_)) { true }
case (_) { false }
};
}
fn fty_args(&ctx cx, ty::t fty) -> vec[ty::arg] {
ret alt (ty::struct(*cx.tcx, fty)) {
case (ty::ty_fn(_, ?args, _, _, _)) { args }
case (ty::ty_native_fn(_, ?args, _)) { args }
};
case (ty::ty_fn(_, ?args, _, _, _)) { args }
case (ty::ty_native_fn(_, ?args, _)) { args }
};
}
// Local Variables:
// mode: rust
// fill-column: 78;

View File

@ -557,8 +557,8 @@ fn encode_info_for_item(@trans::crate_ctxt cx, &ebml::writer ebml_w,
encode_variant_id(ebml_w, v.node.id);
}
ebml::end_tag(ebml_w);
encode_tag_variant_info(cx, ebml_w, item.id, variants,
index, tps);
encode_tag_variant_info(cx, ebml_w, item.id, variants, index,
tps);
}
case (ast::item_obj(_, ?tps, ?ctor_id)) {
ebml::start_tag(ebml_w, tag_items_data_item);

View File

@ -120,18 +120,19 @@ type env =
ext_hash ext_cache,
session sess);
// Used to distinguish between lookups from outside and from inside modules,
// since export restrictions should only be applied for the former.
tag dir { inside; outside; }
tag namespace { ns_value; ns_type; ns_module; }
fn resolve_crate(session sess, @ast::crate crate)
-> tup(def_map, constr_table) {
fn resolve_crate(session sess, @ast::crate crate) ->
tup(def_map, constr_table) {
auto e =
@rec(crate_map=new_uint_hash[ast::crate_num](),
def_map=new_uint_hash[def](),
fn_constrs = new_def_hash[vec[ty::constr_def]](),
fn_constrs=new_def_hash[vec[ty::constr_def]](),
ast_map=new_def_hash[@ast::item](),
imports=new_int_hash[import_state](),
mod_map=new_int_hash[@indexed_mod](),
@ -198,9 +199,7 @@ fn map_crate(&@env e, &@ast::crate c) {
e.ast_map.insert(i.id, i);
e.ast_map.insert(ctor_id, i);
}
case (_) {
e.ast_map.insert(i.id, i);
}
case (_) { e.ast_map.insert(i.id, i); }
}
}
// Next, assemble the links for globbed imports.
@ -260,9 +259,8 @@ fn resolve_names(&@env e, &@ast::crate c) {
visit_arm=bind walk_arm(e, _, _, _),
visit_expr=bind walk_expr(e, _, _, _),
visit_ty=bind walk_ty(e, _, _, _),
visit_constr = bind walk_constr(e, _, _, _),
visit_fn=bind visit_fn_with_scope
(e, _, _, _, _, _, _, _, _)
visit_constr=bind walk_constr(e, _, _, _),
visit_fn=bind visit_fn_with_scope(e, _, _, _, _, _, _, _, _)
with *visit::default_visitor());
visit::visit_crate(*c, cons(scope_crate(c), @nil), visit::vtor(v));
fn walk_expr(@env e, &@ast::expr exp, &scopes sc, &vt[scopes] v) {
@ -277,7 +275,6 @@ fn resolve_names(&@env e, &@ast::crate c) {
case (_) { }
}
}
fn walk_ty(@env e, &@ast::ty t, &scopes sc, &vt[scopes] v) {
visit::visit_ty(t, sc, v);
alt (t.node) {
@ -290,13 +287,12 @@ fn resolve_names(&@env e, &@ast::crate c) {
case (_) { }
}
}
fn walk_constr(@env e, &@ast::constr c, &scopes sc, &vt[scopes] v) {
auto new_def = lookup_path_strict(*e, sc, c.span,
c.node.path.node.idents, ns_value);
auto new_def =
lookup_path_strict(*e, sc, c.span, c.node.path.node.idents,
ns_value);
e.def_map.insert(c.node.ann.id, new_def);
}
fn walk_arm(@env e, &ast::arm a, &scopes sc, &vt[scopes] v) {
walk_pat(*e, sc, a.pat);
visit_arm_with_scope(a, sc, v);
@ -340,11 +336,12 @@ fn visit_fn_with_scope(&@env e, &ast::_fn f, &vec[ast::ty_param] tp, &span sp,
&vt[scopes] v) {
// here's where we need to set up the mapping
// for f's constrs in the table.
for (@ast::constr c in f.decl.constraints) {
resolve_constr(e, d_id, c, sc, v);
resolve_constr(e, d_id, c, sc, v);
}
visit::visit_fn(f, tp, sp, name, d_id, a,
cons(scope_fn(f.decl, tp), @sc), v);
visit::visit_fn(f, tp, sp, name, d_id, a, cons(scope_fn(f.decl, tp), @sc),
v);
}
fn visit_block_with_scope(&ast::block b, &scopes sc, &vt[scopes] v) {
@ -393,36 +390,32 @@ fn follow_import(&env e, &scopes sc, vec[ident] path, &span sp) -> def {
fn resolve_constr(@env e, &def_id d_id, &@ast::constr c, &scopes sc,
&vt[scopes] v) {
let def new_def = lookup_path_strict(*e, sc, c.span,
c.node.path.node.idents,
ns_value);
let def new_def =
lookup_path_strict(*e, sc, c.span, c.node.path.node.idents, ns_value);
alt (new_def) {
case (ast::def_fn(?pred_id)) {
let ty::constr_general[uint] c_ = rec(path=c.node.path,
args=c.node.args,
id=pred_id);
let ty::constr_general[uint] c_ =
rec(path=c.node.path, args=c.node.args, id=pred_id);
let ty::constr_def new_constr = respan(c.span, c_);
add_constr(e, d_id, new_constr);
}
case (_) {
e.sess.span_err(c.span, "Non-predicate in constraint: "
+ ty::path_to_str(c.node.path));
e.sess.span_err(c.span,
"Non-predicate in constraint: " +
ty::path_to_str(c.node.path));
}
}
}
fn add_constr(&@env e, &def_id d_id, &ty::constr_def c) {
e.fn_constrs.insert(d_id,
alt (e.fn_constrs.find(d_id)) {
case (none) {
[c]
}
case (some(?cs)) {
cs + [c]
}
});
alt (e.fn_constrs.find(d_id)) {
case (none) { [c] }
case (some(?cs)) { cs + [c] }
});
}
// Import resolution
fn resolve_import(&env e, &@ast::view_item it, &scopes sc) {
auto defid;
@ -701,7 +694,7 @@ fn lookup_in_block(&ident id, &ast::block_ b, namespace ns) ->
} else if (ns == ns_value) {
for (ast::variant v in variants) {
if (str::eq(v.node.name, id)) {
auto i = v.node.id;
auto i = v.node.id;
ret some(ast::def_variant(it.id,
i));
}

View File

@ -113,6 +113,7 @@ type stats =
mutable uint n_null_glues,
mutable uint n_real_glues);
// Crate context. Every crate we compile has one of these.
type crate_ctxt =
rec(session::session sess,
@ -437,9 +438,10 @@ fn T_task(&type_names tn) -> TypeRef {
T_int(), // Runtime SP
T_int(), // Rust SP
T_int(), // GC chain
T_int(), // Domain pointer
// Crate cache pointer
T_int()]);
T_int(), // Domain pointer
// Crate cache pointer
T_int()]);
tn.associate(s, t);
ret t;
}
@ -514,9 +516,10 @@ fn T_vec(TypeRef t) -> TypeRef {
ret T_struct([T_int(), // Refcount
T_int(), // Alloc
T_int(), // Fill
T_int(), // Pad
// Body elements
T_array(t, 0u)]);
T_int(), // Pad
// Body elements
T_array(t, 0u)]);
}
fn T_opaque_vec_ptr() -> TypeRef { ret T_ptr(T_vec(T_int())); }
@ -1627,6 +1630,7 @@ fn get_derived_tydesc(&@block_ctxt cx, &ty::t t, bool escapes,
if (escapes) {
auto tydescs =
alloca(bcx, /* for root*/
T_array(T_ptr(T_tydesc(bcx.fcx.lcx.ccx.tn)),
1u + n_params));
auto i = 0;
@ -2168,12 +2172,13 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,
auto rhs_fill;
auto bcx;
if (ty::sequence_is_interior(cx.fcx.lcx.ccx.tcx, t)) {
auto lad = ivec::get_len_and_data(scx, lhs,
ty::sequence_element_type(cx.fcx.lcx.ccx.tcx, t));
auto st = ty::sequence_element_type(cx.fcx.lcx.ccx.tcx, t);
auto lad =
ivec::get_len_and_data(scx, lhs, st);
bcx = lad._2;
lhs_fill = lad._0;
lad = ivec::get_len_and_data(bcx, rhs,
ty::sequence_element_type(cx.fcx.lcx.ccx.tcx, t));
lad =
ivec::get_len_and_data(bcx, rhs, st);
bcx = lad._2;
rhs_fill = lad._0;
} else {
@ -2181,8 +2186,8 @@ fn make_cmp_glue(&@block_ctxt cx, ValueRef lhs0, ValueRef rhs0, &ty::t t,
rhs_fill = vec_fill(scx, rhs);
bcx = scx;
}
r = compare_numerical_values(bcx, lhs_fill, rhs_fill,
r =
compare_numerical_values(bcx, lhs_fill, rhs_fill,
unsigned_int, llop);
r.bcx.build.Store(r.val, flag);
} else {
@ -2435,7 +2440,7 @@ fn get_len_and_data(&@block_ctxt bcx, ValueRef v, ty::t unit_ty) ->
auto heap_len =
{
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_len)];
auto m = nonzero_len_cx.build.InBoundsGEP(heap_ptr,v);
auto m = nonzero_len_cx.build.InBoundsGEP(heap_ptr, v);
nonzero_len_cx.build.Load(m)
};
auto heap_elem =
@ -2502,12 +2507,10 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
auto rslt = size_of(bcx, unit_ty);
auto unit_sz = rslt.val;
bcx = rslt.bcx;
auto a_len_and_data = ivec::get_len_and_data(bcx, av, unit_ty);
auto a_len = a_len_and_data._0;
auto a_elem = a_len_and_data._1;
bcx = a_len_and_data._2;
auto b_len_and_data = ivec::get_len_and_data(bcx, bv, unit_ty);
auto b_len = b_len_and_data._0;
auto b_elem = b_len_and_data._1;
@ -2608,8 +2611,8 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
variant_cx = rslt.bcx;
auto tcx = cx.fcx.lcx.ccx.tcx;
auto ty_subst =
ty::substitute_type_params(tcx,
tps, a.ty);
ty::substitute_type_params(tcx, tps,
a.ty);
auto llfld_a =
load_if_immediate(variant_cx, llfldp_a,
ty_subst);
@ -2664,11 +2667,14 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
// Iterates through a pointer range, until the src* hits the src_lim*.
fn iter_sequence_raw(@block_ctxt cx, ValueRef dst,
// elt*
// elt*
ValueRef src,
// elt*
// elt*
ValueRef src_lim,
// elt*
// elt*
ValueRef elt_sz, &val_pair_fn f) -> result {
auto bcx = cx;
let ValueRef dst_int = vp2i(bcx, dst);
@ -2696,7 +2702,8 @@ fn iter_sequence_raw(@block_ctxt cx, ValueRef dst,
}
fn iter_sequence_inner(&@block_ctxt cx, ValueRef src,
// elt*
// elt*
ValueRef src_lim,
& // elt*
ty::t elt_ty, &val_and_ty_fn f) -> result {
@ -3043,7 +3050,7 @@ fn move_val(@block_ctxt cx, copy_action action, ValueRef dst, ValueRef src,
ty::type_is_native(cx.fcx.lcx.ccx.tcx, t)) {
ret res(cx, cx.build.Store(src, dst));
} else if (ty::type_is_nil(cx.fcx.lcx.ccx.tcx, t) ||
ty::type_is_bot(cx.fcx.lcx.ccx.tcx, t)) {
ty::type_is_bot(cx.fcx.lcx.ccx.tcx, t)) {
ret res(cx, C_nil());
} else if (ty::type_is_boxed(cx.fcx.lcx.ccx.tcx, t)) {
if (action == DROP_EXISTING) {
@ -3231,31 +3238,37 @@ fn trans_vec_append(&@block_ctxt cx, &ty::t t, ValueRef lhs, ValueRef rhs) ->
llelt_tydesc.val, dst, src, skip_null]));
}
mod ivec {
// Returns the length of an interior vector and a pointer to its first
// element, in that order.
fn get_len_and_data(&@block_ctxt bcx, ValueRef v, ty::t unit_ty) ->
tup(ValueRef, ValueRef, @block_ctxt) {
tup(ValueRef, ValueRef, @block_ctxt) {
auto llunitty = type_of_or_i8(bcx, unit_ty);
auto stack_len =
bcx.build.Load(bcx.build.InBoundsGEP(v,
[C_int(0), C_uint(abi::ivec_elt_len)]));
{
auto p = bcx.build.InBoundsGEP(v,
[C_int(0),
C_uint(abi::ivec_elt_len)]);
bcx.build.Load(p)
};
auto stack_elem =
bcx.build.InBoundsGEP(v,
[C_int(0), C_uint(abi::ivec_elt_elems), C_int(0)]);
auto on_heap = bcx.build.ICmp(lib::llvm::LLVMIntEQ, stack_len,
C_int(0));
[C_int(0), C_uint(abi::ivec_elt_elems),
C_int(0)]);
auto on_heap =
bcx.build.ICmp(lib::llvm::LLVMIntEQ, stack_len, C_int(0));
auto on_heap_cx = new_sub_block_ctxt(bcx, "on_heap");
auto next_cx = new_sub_block_ctxt(bcx, "next");
bcx.build.CondBr(on_heap, on_heap_cx.llbb, next_cx.llbb);
auto heap_stub =
on_heap_cx.build.PointerCast(v, T_ptr(T_ivec_heap(llunitty)));
auto heap_ptr = {
auto v = [C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)];
on_heap_cx.build.Load(on_heap_cx.build.InBoundsGEP(heap_stub, v))
};
auto heap_ptr =
{
auto v = [C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)];
on_heap_cx.build.Load(on_heap_cx.build.InBoundsGEP(heap_stub,
v))
};
// Check whether the heap pointer is null. If it is, the vector length
// is truly zero.
@ -3276,27 +3289,31 @@ mod ivec {
zero_len_cx.build.Br(next_cx.llbb);
// If we're here, then we actually have a heapified vector.
auto heap_len = {
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_len)];
auto m = nonzero_len_cx.build.InBoundsGEP(heap_ptr, v);
nonzero_len_cx.build.Load(m)
};
auto heap_len =
{
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_len)];
auto m = nonzero_len_cx.build.InBoundsGEP(heap_ptr, v);
nonzero_len_cx.build.Load(m)
};
auto heap_elem =
nonzero_len_cx.build.InBoundsGEP(heap_ptr,
[C_int(0), C_uint(abi::ivec_heap_elt_elems), C_int(0)]);
{
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_elems),
C_int(0)];
nonzero_len_cx.build.InBoundsGEP(heap_ptr,v)
};
nonzero_len_cx.build.Br(next_cx.llbb);
// Now we can figure out the length of `v` and get a pointer to its
// first element.
auto len =
next_cx.build.Phi(T_int(),
[stack_len, zero_len, heap_len],
[bcx.llbb, zero_len_cx.llbb, nonzero_len_cx.llbb]);
next_cx.build.Phi(T_int(), [stack_len, zero_len, heap_len],
[bcx.llbb, zero_len_cx.llbb,
nonzero_len_cx.llbb]);
auto elem =
next_cx.build.Phi(T_ptr(llunitty),
[stack_elem, zero_elem, heap_elem],
[bcx.llbb, zero_len_cx.llbb, nonzero_len_cx.llbb]);
[stack_elem, zero_elem, heap_elem],
[bcx.llbb, zero_len_cx.llbb,
nonzero_len_cx.llbb]);
ret tup(len, elem, next_cx);
}
@ -3327,9 +3344,9 @@ mod ivec {
// We're possibly on the heap, unless the vector is zero-length.
auto stub_p = [C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)];
auto stub_ptr = maybe_on_heap_cx.build.PointerCast(v,
T_ptr(T_ivec_heap(llunitty)));
auto stub_ptr =
maybe_on_heap_cx.build.PointerCast(v,
T_ptr(T_ivec_heap(llunitty)));
auto heap_ptr =
{
auto m = maybe_on_heap_cx.build.InBoundsGEP(stub_ptr, stub_p);
@ -3341,8 +3358,8 @@ mod ivec {
auto on_heap_cx = new_sub_block_ctxt(cx, "on_heap");
maybe_on_heap_cx.build.CondBr(on_heap, on_heap_cx.llbb,
on_stack_cx.llbb);
// We're definitely on the heap. Check whether we need to resize.
auto heap_len_ptr =
on_heap_cx.build.InBoundsGEP(heap_ptr,
[C_int(0),
@ -3360,35 +3377,36 @@ mod ivec {
// Case (1): We're on the heap and don't need to resize.
auto heap_data_no_resize =
heap_no_resize_cx.build.InBoundsGEP(heap_ptr,
[C_int(0),
C_uint(abi::ivec_heap_elt_elems),
heap_len_unscaled]);
{
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_elems),
heap_len_unscaled];
heap_no_resize_cx.build.InBoundsGEP(heap_ptr,v)
};
heap_no_resize_cx.build.Store(new_heap_len, heap_len_ptr);
heap_no_resize_cx.build.Br(next_cx.llbb);
// Case (2): We're on the heap and need to resize. This path is rare,
// so we delegate to cold glue.
{
auto p = heap_resize_cx.build.PointerCast(v,
T_ptr(T_opaque_ivec()));
auto p =
heap_resize_cx.build.PointerCast(v, T_ptr(T_opaque_ivec()));
heap_resize_cx.build.Call(cx.fcx.lcx.ccx.upcalls.ivec_resize,
[cx.fcx.lltaskptr, p, new_heap_len]);
}
auto heap_ptr_resize = {
auto m = heap_resize_cx.build.InBoundsGEP(stub_ptr, stub_p);
heap_resize_cx.build.Load(m)
};
auto heap_ptr_resize =
{
auto m = heap_resize_cx.build.InBoundsGEP(stub_ptr, stub_p);
heap_resize_cx.build.Load(m)
};
auto heap_data_resize =
heap_resize_cx.build.InBoundsGEP(heap_ptr_resize,
[C_int(0),
C_uint(abi::ivec_heap_elt_elems),
heap_len_unscaled]);
{
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_elems),
heap_len_unscaled];
heap_resize_cx.build.InBoundsGEP(heap_ptr_resize, v)
};
heap_resize_cx.build.Br(next_cx.llbb);
// We're on the stack. Check whether we need to spill to the heap.
auto new_stack_len = on_stack_cx.build.Add(stack_len, len_needed);
auto stack_no_spill_needed =
on_stack_cx.build.ICmp(lib::llvm::LLVMIntULE, new_stack_len,
@ -3398,10 +3416,9 @@ mod ivec {
auto stack_no_spill_cx = new_sub_block_ctxt(cx, "stack_no_spill");
auto stack_spill_cx = new_sub_block_ctxt(cx, "stack_spill");
on_stack_cx.build.CondBr(stack_no_spill_needed,
stack_no_spill_cx.llbb,
stack_spill_cx.llbb);
stack_no_spill_cx.llbb, stack_spill_cx.llbb);
// Case (3): We're on the stack and don't need to spill.
auto stack_data_no_spill =
stack_no_spill_cx.build.InBoundsGEP(v,
[C_int(0),
@ -3409,32 +3426,36 @@ mod ivec {
stack_len_unscaled]);
stack_no_spill_cx.build.Store(new_stack_len, stack_len_ptr);
stack_no_spill_cx.build.Br(next_cx.llbb);
// Case (4): We're on the stack and need to spill. Like case (2), this
// path is rare, so we delegate to cold glue.
{
auto p = stack_spill_cx.build.PointerCast(v,
T_ptr(T_opaque_ivec()));
auto p =
stack_spill_cx.build.PointerCast(v, T_ptr(T_opaque_ivec()));
stack_spill_cx.build.Call(cx.fcx.lcx.ccx.upcalls.ivec_spill,
[cx.fcx.lltaskptr, p, new_stack_len]);
}
auto spill_stub =
stack_spill_cx.build.PointerCast(v, T_ptr(T_ivec_heap(llunitty)));
auto heap_ptr_spill =
stack_spill_cx.build.Load(
stack_spill_cx.build.InBoundsGEP(spill_stub, stub_p));
{
auto p = stack_spill_cx.build.InBoundsGEP(spill_stub, stub_p);
stack_spill_cx.build.Load(p)
};
auto heap_len_ptr_spill =
stack_spill_cx.build.InBoundsGEP(heap_ptr_spill,
[C_int(0), C_uint(abi::ivec_heap_elt_len)]);
{
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_len)];
stack_spill_cx.build.InBoundsGEP(heap_ptr_spill, v)
};
auto heap_data_spill =
stack_spill_cx.build.InBoundsGEP(heap_ptr_spill,
[C_int(0),
C_uint(abi::ivec_heap_elt_elems),
stack_len_unscaled]);
{
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_elems),
stack_len_unscaled];
stack_spill_cx.build.InBoundsGEP(heap_ptr_spill, v)
};
stack_spill_cx.build.Br(next_cx.llbb);
// Phi together the different data pointers to get the result.
auto data_ptr =
next_cx.build.Phi(T_ptr(llunitty),
[heap_data_no_resize, heap_data_resize,
@ -3443,7 +3464,6 @@ mod ivec {
stack_no_spill_cx.llbb, stack_spill_cx.llbb]);
ret res(next_cx, data_ptr);
}
fn trans_append(&@block_ctxt cx, &ty::t t, ValueRef lhs, ValueRef rhs) ->
result {
auto unit_ty = ty::sequence_element_type(cx.fcx.lcx.ccx.tcx, t);
@ -3468,45 +3488,41 @@ mod ivec {
rslt = get_tydesc(bcx, unit_ty, false, no_tydesc_info);
auto unit_tydesc = rslt.val;
bcx = rslt.bcx;
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_take_glue, none);
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_drop_glue, none);
lazily_emit_tydesc_glue(bcx, abi::tydesc_field_free_glue, none);
auto rhs_len_and_data = get_len_and_data(bcx, rhs, unit_ty);
auto rhs_len = rhs_len_and_data._0;
auto rhs_data = rhs_len_and_data._1;
bcx = rhs_len_and_data._2;
rslt = reserve_space(bcx, llunitty, lhs, rhs_len);
auto lhs_data = rslt.val;
bcx = rslt.bcx;
// Work out the end pointer.
auto lhs_unscaled_idx = bcx.build.UDiv(rhs_len, llsize_of(llunitty));
auto lhs_end = bcx.build.InBoundsGEP(lhs_data, [lhs_unscaled_idx]);
// Now emit the copy loop.
auto dest_ptr = alloca(bcx, T_ptr(llunitty));
bcx.build.Store(lhs_data, dest_ptr);
auto src_ptr = alloca(bcx, T_ptr(llunitty));
bcx.build.Store(rhs_data, src_ptr);
auto copy_loop_header_cx = new_sub_block_ctxt(bcx,
"copy_loop_header");
auto copy_loop_header_cx =
new_sub_block_ctxt(bcx, "copy_loop_header");
bcx.build.Br(copy_loop_header_cx.llbb);
auto copy_dest_ptr = copy_loop_header_cx.build.Load(dest_ptr);
auto not_yet_at_end =
copy_loop_header_cx.build.ICmp(lib::llvm::LLVMIntNE,
copy_dest_ptr,
lhs_end);
copy_dest_ptr, lhs_end);
auto copy_loop_body_cx = new_sub_block_ctxt(bcx, "copy_loop_body");
auto next_cx = new_sub_block_ctxt(bcx, "next");
copy_loop_header_cx.build.CondBr(not_yet_at_end,
copy_loop_body_cx.llbb,
next_cx.llbb);
auto copy_src_ptr = copy_loop_body_cx.build.Load(src_ptr);
rslt = copy_val(copy_loop_body_cx, INIT, copy_dest_ptr, copy_src_ptr,
t);
rslt =
copy_val(copy_loop_body_cx, INIT, copy_dest_ptr, copy_src_ptr, t);
auto post_copy_cx = rslt.bcx;
// Increment both pointers.
@ -3519,175 +3535,192 @@ mod ivec {
post_copy_cx.build.Br(copy_loop_header_cx.llbb);
ret res(next_cx, C_nil());
}
fn alloc(&@block_ctxt bcx, ty::t unit_ty, ValueRef llalen) -> ValueRef {
auto llunitty = type_of_or_i8(bcx, unit_ty);
if (ty::type_has_dynamic_size(bcx.fcx.lcx.ccx.tcx, unit_ty)) {
auto llarraysz = bcx.build.Add(llsize_of(T_opaque_ivec()),
llalen);
auto llarraysz =
bcx.build.Add(llsize_of(T_opaque_ivec()), llalen);
auto llvecptr = array_alloca(bcx, T_i8(), llarraysz);
ret bcx.build.PointerCast(llvecptr, T_ptr(T_opaque_ivec()));
}
ret alloca(bcx, T_ivec(llunitty));
}
fn trans_add(&@block_ctxt cx, ty::t vec_ty, ValueRef lhs, ValueRef rhs)
-> result {
fn trans_add(&@block_ctxt cx, ty::t vec_ty, ValueRef lhs, ValueRef rhs) ->
result {
auto bcx = cx;
auto unit_ty = ty::sequence_element_type(bcx.fcx.lcx.ccx.tcx, vec_ty);
auto rslt = size_of(bcx, unit_ty);
auto unit_sz = rslt.val;
auto llalen = bcx.build.Mul(unit_sz,
C_uint(abi::ivec_default_length));
auto llalen =
bcx.build.Mul(unit_sz, C_uint(abi::ivec_default_length));
auto llvecptr = alloc(bcx, unit_ty, llalen);
auto llunitty = type_of_or_i8(bcx, unit_ty);
auto llheappartty = T_ivec_heap_part(llunitty);
auto lhs_len_and_data = get_len_and_data(bcx, lhs, unit_ty);
auto lhs_len = lhs_len_and_data._0;
auto lhs_data = lhs_len_and_data._1;
bcx = lhs_len_and_data._2;
auto rhs_len_and_data = get_len_and_data(bcx, rhs, unit_ty);
auto rhs_len = rhs_len_and_data._0;
auto rhs_data = rhs_len_and_data._1;
bcx = rhs_len_and_data._2;
auto lllen = bcx.build.Add(lhs_len, rhs_len);
// We have three cases to handle here:
// (1) Length is zero ([] + []).
// (2) Copy onto stack.
// (3) Allocate on heap and copy there.
auto len_is_zero = bcx.build.ICmp(lib::llvm::LLVMIntEQ, lllen,
C_int(0));
auto len_is_zero =
bcx.build.ICmp(lib::llvm::LLVMIntEQ, lllen, C_int(0));
auto zero_len_cx = new_sub_block_ctxt(bcx, "zero_len");
auto nonzero_len_cx = new_sub_block_ctxt(bcx, "nonzero_len");
bcx.build.CondBr(len_is_zero, zero_len_cx.llbb, nonzero_len_cx.llbb);
// Case (1): Length is zero.
auto stub_ptr_zero = zero_len_cx.build.PointerCast(llvecptr,
T_ptr(T_ivec_heap(llunitty)));
zero_len_cx.build.Store(C_int(0), zero_len_cx.build.InBoundsGEP(
stub_ptr_zero, [C_int(0), C_uint(abi::ivec_heap_stub_elt_zero)]));
zero_len_cx.build.Store(llalen, zero_len_cx.build.InBoundsGEP(
stub_ptr_zero, [C_int(0), C_uint(abi::ivec_heap_stub_elt_alen)]));
auto stub_z = [C_int(0), C_uint(abi::ivec_heap_stub_elt_zero)];
auto stub_a = [C_int(0), C_uint(abi::ivec_heap_stub_elt_alen)];
auto stub_p = [C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)];
auto vec_l = [C_int(0), C_uint(abi::ivec_elt_len)];
auto vec_a = [C_int(0), C_uint(abi::ivec_elt_alen)];
auto stub_ptr_zero =
zero_len_cx.build.PointerCast(llvecptr,
T_ptr(T_ivec_heap(llunitty)));
zero_len_cx.build.Store(C_int(0),
zero_len_cx.build.InBoundsGEP(stub_ptr_zero,
stub_z));
zero_len_cx.build.Store(llalen,
zero_len_cx.build.InBoundsGEP(stub_ptr_zero,
stub_a));
zero_len_cx.build.Store(C_null(T_ptr(llheappartty)),
zero_len_cx.build.InBoundsGEP(stub_ptr_zero,
[C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)]));
zero_len_cx.build.InBoundsGEP(stub_ptr_zero,
stub_p));
auto next_cx = new_sub_block_ctxt(bcx, "next");
zero_len_cx.build.Br(next_cx.llbb);
// Determine whether we need to spill to the heap.
auto on_stack = nonzero_len_cx.build.ICmp(lib::llvm::LLVMIntULE,
lllen, llalen);
auto on_stack =
nonzero_len_cx.build.ICmp(lib::llvm::LLVMIntULE, lllen, llalen);
auto stack_cx = new_sub_block_ctxt(bcx, "stack");
auto heap_cx = new_sub_block_ctxt(bcx, "heap");
nonzero_len_cx.build.CondBr(on_stack, stack_cx.llbb, heap_cx.llbb);
// Case (2): Copy onto stack.
stack_cx.build.Store(lllen, stack_cx.build.InBoundsGEP(llvecptr,
[C_int(0), C_uint(abi::ivec_elt_len)]));
stack_cx.build.Store(llalen, stack_cx.build.InBoundsGEP(llvecptr,
[C_int(0), C_uint(abi::ivec_elt_alen)]));
auto dest_ptr_stack = stack_cx.build.InBoundsGEP(llvecptr,
[C_int(0), C_uint(abi::ivec_elt_elems), C_int(0)]);
stack_cx.build.Store(lllen,
stack_cx.build.InBoundsGEP(llvecptr, vec_l));
stack_cx.build.Store(llalen,
stack_cx.build.InBoundsGEP(llvecptr, vec_a));
auto dest_ptr_stack =
stack_cx.build.InBoundsGEP(llvecptr,
[C_int(0), C_uint(abi::ivec_elt_elems),
C_int(0)]);
auto copy_cx = new_sub_block_ctxt(bcx, "copy");
stack_cx.build.Br(copy_cx.llbb);
// Case (3): Allocate on heap and copy there.
auto stub_ptr_heap = heap_cx.build.PointerCast(llvecptr,
T_ptr(T_ivec_heap(llunitty)));
heap_cx.build.Store(C_int(0), heap_cx.build.InBoundsGEP(
stub_ptr_heap, [C_int(0), C_uint(abi::ivec_heap_stub_elt_zero)]));
heap_cx.build.Store(lllen, heap_cx.build.InBoundsGEP(
stub_ptr_heap, [C_int(0), C_uint(abi::ivec_heap_stub_elt_alen)]));
auto stub_ptr_heap =
heap_cx.build.PointerCast(llvecptr, T_ptr(T_ivec_heap(llunitty)));
heap_cx.build.Store(C_int(0),
heap_cx.build.InBoundsGEP(stub_ptr_heap,
stub_z));
heap_cx.build.Store(lllen,
heap_cx.build.InBoundsGEP(stub_ptr_heap,
stub_a));
auto heap_sz = heap_cx.build.Add(llsize_of(llheappartty), lllen);
rslt = trans_raw_malloc(heap_cx, T_ptr(llheappartty), heap_sz);
auto heap_part = rslt.val;
heap_cx = rslt.bcx;
heap_cx.build.Store(heap_part, heap_cx.build.InBoundsGEP(
stub_ptr_heap, [C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)]));
heap_cx.build.Store(lllen, heap_cx.build.InBoundsGEP(heap_part,
[C_int(0), C_uint(abi::ivec_heap_elt_len)]));
auto dest_ptr_heap = heap_cx.build.InBoundsGEP(heap_part,
[C_int(0), C_uint(abi::ivec_heap_elt_elems), C_int(0)]);
heap_cx.build.Store(heap_part,
heap_cx.build.InBoundsGEP(stub_ptr_heap,
stub_p));
{
auto v = [C_int(0), C_uint(abi::ivec_heap_elt_len)];
heap_cx.build.Store(lllen,
heap_cx.build.InBoundsGEP(heap_part,
v));
}
auto dest_ptr_heap =
heap_cx.build.InBoundsGEP(heap_part,
[C_int(0),
C_uint(abi::ivec_heap_elt_elems),
C_int(0)]);
heap_cx.build.Br(copy_cx.llbb);
// Emit the copy loop.
auto first_dest_ptr = copy_cx.build.Phi(T_ptr(llunitty),
[dest_ptr_stack, dest_ptr_heap], [stack_cx.llbb, heap_cx.llbb]);
auto first_dest_ptr =
copy_cx.build.Phi(T_ptr(llunitty),
[dest_ptr_stack, dest_ptr_heap],
[stack_cx.llbb, heap_cx.llbb]);
auto lhs_len_unscaled = copy_cx.build.UDiv(lhs_len, unit_sz);
auto lhs_end_ptr = copy_cx.build.InBoundsGEP(lhs_data,
[lhs_len_unscaled]);
auto lhs_end_ptr =
copy_cx.build.InBoundsGEP(lhs_data, [lhs_len_unscaled]);
auto rhs_len_unscaled = copy_cx.build.UDiv(rhs_len, unit_sz);
auto rhs_end_ptr = copy_cx.build.InBoundsGEP(rhs_data,
[rhs_len_unscaled]);
auto rhs_end_ptr =
copy_cx.build.InBoundsGEP(rhs_data, [rhs_len_unscaled]);
auto dest_ptr_ptr = alloca(copy_cx, T_ptr(llunitty));
copy_cx.build.Store(first_dest_ptr, dest_ptr_ptr);
auto lhs_ptr_ptr = alloca(copy_cx, T_ptr(llunitty));
copy_cx.build.Store(lhs_data, lhs_ptr_ptr);
auto rhs_ptr_ptr = alloca(copy_cx, T_ptr(llunitty));
copy_cx.build.Store(rhs_data, rhs_ptr_ptr);
auto lhs_copy_cx = new_sub_block_ctxt(bcx, "lhs_copy");
copy_cx.build.Br(lhs_copy_cx.llbb);
// Copy in elements from the LHS.
auto lhs_ptr = lhs_copy_cx.build.Load(lhs_ptr_ptr);
auto not_at_end_lhs = lhs_copy_cx.build.ICmp(lib::llvm::LLVMIntNE,
lhs_ptr, lhs_end_ptr);
auto not_at_end_lhs =
lhs_copy_cx.build.ICmp(lib::llvm::LLVMIntNE, lhs_ptr,
lhs_end_ptr);
auto lhs_do_copy_cx = new_sub_block_ctxt(bcx, "lhs_do_copy");
auto rhs_copy_cx = new_sub_block_ctxt(bcx, "rhs_copy");
lhs_copy_cx.build.CondBr(not_at_end_lhs, lhs_do_copy_cx.llbb,
rhs_copy_cx.llbb);
auto dest_ptr_lhs_copy = lhs_do_copy_cx.build.Load(dest_ptr_ptr);
auto lhs_val = load_if_immediate(lhs_do_copy_cx, lhs_ptr, unit_ty);
rslt = copy_val(lhs_do_copy_cx, INIT, dest_ptr_lhs_copy, lhs_val,
unit_ty);
rslt =
copy_val(lhs_do_copy_cx, INIT, dest_ptr_lhs_copy, lhs_val,
unit_ty);
lhs_do_copy_cx = rslt.bcx;
lhs_do_copy_cx.build.Store(lhs_do_copy_cx.build.InBoundsGEP(
dest_ptr_lhs_copy, [C_int(1)]), dest_ptr_ptr);
lhs_do_copy_cx.build.Store(lhs_do_copy_cx.build.InBoundsGEP(
lhs_ptr, [C_int(1)]), lhs_ptr_ptr);
{
auto d = lhs_do_copy_cx.build.InBoundsGEP(dest_ptr_lhs_copy,
[C_int(1)]);
auto lhs = lhs_do_copy_cx.build.InBoundsGEP(lhs_ptr,
[C_int(1)]);
lhs_do_copy_cx.build.Store(d, dest_ptr_ptr);
lhs_do_copy_cx.build.Store(lhs, lhs_ptr_ptr);
}
lhs_do_copy_cx.build.Br(lhs_copy_cx.llbb);
// Copy in elements from the RHS.
auto rhs_ptr = rhs_copy_cx.build.Load(rhs_ptr_ptr);
auto not_at_end_rhs = rhs_copy_cx.build.ICmp(lib::llvm::LLVMIntNE,
rhs_ptr, rhs_end_ptr);
auto not_at_end_rhs =
rhs_copy_cx.build.ICmp(lib::llvm::LLVMIntNE, rhs_ptr,
rhs_end_ptr);
auto rhs_do_copy_cx = new_sub_block_ctxt(bcx, "rhs_do_copy");
rhs_copy_cx.build.CondBr(not_at_end_rhs, rhs_do_copy_cx.llbb,
next_cx.llbb);
auto dest_ptr_rhs_copy = rhs_do_copy_cx.build.Load(dest_ptr_ptr);
auto rhs_val = load_if_immediate(rhs_do_copy_cx, rhs_ptr, unit_ty);
rslt = copy_val(rhs_do_copy_cx, INIT, dest_ptr_rhs_copy, rhs_val,
unit_ty);
rslt =
copy_val(rhs_do_copy_cx, INIT, dest_ptr_rhs_copy, rhs_val,
unit_ty);
rhs_do_copy_cx = rslt.bcx;
rhs_do_copy_cx.build.Store(rhs_do_copy_cx.build.InBoundsGEP(
dest_ptr_rhs_copy, [C_int(1)]), dest_ptr_ptr);
rhs_do_copy_cx.build.Store(rhs_do_copy_cx.build.InBoundsGEP(
rhs_ptr, [C_int(1)]), rhs_ptr_ptr);
{
auto d = rhs_do_copy_cx.build.InBoundsGEP(dest_ptr_rhs_copy,
[C_int(1)]);
auto rhs = rhs_do_copy_cx.build.InBoundsGEP(rhs_ptr,
[C_int(1)]);
rhs_do_copy_cx.build.Store(d, dest_ptr_ptr);
rhs_do_copy_cx.build.Store(rhs, rhs_ptr_ptr);
}
rhs_do_copy_cx.build.Br(rhs_copy_cx.llbb);
// Finally done!
ret res(next_cx, llvecptr);
}
}
fn trans_vec_add(&@block_ctxt cx, &ty::t t, ValueRef lhs, ValueRef rhs) ->
result {
auto r = alloc_ty(cx, t);
@ -4715,9 +4748,9 @@ fn trans_lval(&@block_ctxt cx, &@ast::expr e) -> lval_result {
case (_) {
// Shouldn't happen.
cx.fcx.lcx.ccx.sess.bug("trans_lval called on "
+ "expr_self_method in a context"
+ "without llself");
cx.fcx.lcx.ccx.sess.bug("trans_lval called on " +
"expr_self_method in " +
"a context without llself");
}
}
}
@ -5359,9 +5392,10 @@ fn trans_vec(&@block_ctxt cx, &vec[@ast::expr] args, &ast::ann ann) ->
ret res(bcx, vec_val);
}
// TODO: Move me to ivec::
fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann) ->
result {
result {
auto typ = node_ann_type(bcx.fcx.lcx.ccx, ann);
auto unit_ty;
alt (ty::struct(bcx.fcx.lcx.ccx.tcx, typ)) {
@ -5396,17 +5430,13 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann) ->
} else {
// Heap case.
auto stub_z = [C_int(0), C_uint(abi::ivec_heap_stub_elt_zero)];
auto stub_a = [C_int(0), C_uint(abi::ivec_heap_stub_elt_alen)];
auto stub_p = [C_int(0), C_uint(abi::ivec_heap_stub_elt_ptr)];
auto llstubty = T_ivec_heap(llunitty);
auto llstubptr = bcx.build.PointerCast(llvecptr, T_ptr(llstubty));
bcx.build.Store(C_int(0),
bcx.build.InBoundsGEP(llstubptr, stub_z));
bcx.build.Store(lllen,
bcx.build.InBoundsGEP(llstubptr, stub_a));
bcx.build.Store(C_int(0), bcx.build.InBoundsGEP(llstubptr, stub_z));
bcx.build.Store(lllen, bcx.build.InBoundsGEP(llstubptr, stub_a));
auto llheapty = T_ivec_heap_part(llunitty);
if (vec::len(args) == 0u) {
// Null heap pointer indicates a zero-length vector.
@ -5422,8 +5452,7 @@ fn trans_ivec(@block_ctxt bcx, &vec[@ast::expr] args, &ast::ann ann) ->
bcx.build.Store(llheapptr,
bcx.build.InBoundsGEP(llstubptr, stub_p));
auto heap_l = [C_int(0), C_uint(abi::ivec_heap_elt_len)];
bcx.build.Store(lllen,
bcx.build.InBoundsGEP(llheapptr, heap_l));
bcx.build.Store(lllen, bcx.build.InBoundsGEP(llheapptr, heap_l));
llfirsteltptr =
bcx.build.InBoundsGEP(llheapptr,
[C_int(0),
@ -5601,14 +5630,15 @@ fn trans_expr_out(&@block_ctxt cx, &@ast::expr e, out_method output) ->
auto rhs_res = trans_lval(lhs_res.res.bcx, src);
auto t = ty::expr_ty(cx.fcx.lcx.ccx.tcx, src);
auto tmp_res = alloc_ty(rhs_res.res.bcx, t);
// Swap through a temporary.
auto move1_res = memmove_ty(tmp_res.bcx, tmp_res.val,
lhs_res.res.val, t);
auto move2_res = memmove_ty(move1_res.bcx, lhs_res.res.val,
rhs_res.res.val, t);
auto move3_res = memmove_ty(move2_res.bcx, rhs_res.res.val,
tmp_res.val, t);
auto move1_res =
memmove_ty(tmp_res.bcx, tmp_res.val, lhs_res.res.val, t);
auto move2_res =
memmove_ty(move1_res.bcx, lhs_res.res.val, rhs_res.res.val,
t);
auto move3_res =
memmove_ty(move2_res.bcx, rhs_res.res.val, tmp_res.val, t);
ret res(move3_res.bcx, C_nil());
}
case (ast::expr_assign_op(?op, ?dst, ?src, _)) {
@ -6141,7 +6171,6 @@ fn mk_spawn_wrapper(&@block_ctxt cx, &@ast::expr func, &ty::t args_ty) ->
mangle_internal_name_by_path_and_seq(cx.fcx.lcx.ccx, cx.fcx.lcx.path,
"spawn_wrapper");
auto llfndecl = decl_cdecl_fn(llmod, wrap_name, wrapper_fn_type);
auto fcx = new_fn_ctxt(cx.fcx.lcx, cx.sp, llfndecl);
auto fbcx = new_top_block_ctxt(fcx);
// 3u to skip the three implicit args
@ -6270,21 +6299,20 @@ fn recv_val(&@block_ctxt cx, ValueRef lhs, &@ast::expr rhs, &ty::t unit_ty,
// function and putting it in the generated code as an object item, we are
// instead "inlining" the construction of the object and returning the object
// itself.
fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
&vec[ast::ty_param] ty_params, ast::def_id oid,
&ast::ann ann) -> result {
// Right now, we're assuming that anon objs don't take ty params, even
// though the AST supports it. It's nonsensical to write an expression
// like "obj[T](){ ... with ... }", since T is never instantiated;
// nevertheless, such an expression will parse. FIXME for the future:
// support typarams (issue #n).
assert vec::len(ty_params) == 0u;
assert (vec::len(ty_params) == 0u);
auto ccx = bcx.fcx.lcx.ccx;
// If with_obj (the object being extended) exists, translate it, producing
// a result.
let option::t[result] with_obj_val = none[result];
alt (anon_obj.with_obj) {
case (none) { }
@ -6296,41 +6324,38 @@ fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
with_obj_val = some[result](trans_expr(bcx, e));
}
}
// FIXME (part of issue #417): all of the following code is copypasta from
// trans_obj for translating the anonymous wrapper object. Eventually we
// should abstract this code out of trans_anon_obj and trans_obj.
auto self_ty = ty::ann_to_type(ccx.tcx, ann);
auto llself_ty = type_of(ccx, sp, self_ty);
// Allocate the object that we're going to return. It's a two-word pair
// containing a vtable pointer and a body pointer.
auto pair = alloca(bcx, llself_ty);
auto pair = alloca(bcx, llself_ty);
// Grab onto the first and second elements of the pair.
// abi::obj_field_vtbl and abi::obj_field_box simply specify words 0 and 1
// of 'pair'.
auto pair_vtbl =
bcx.build.GEP(pair, [C_int(0), C_int(abi::obj_field_vtbl)]);
auto pair_box =
bcx.build.GEP(pair, [C_int(0), C_int(abi::obj_field_box)]);
// Make a vtable for the outer object. create_vtbl() wants an ast::_obj
// and all we have is an ast::anon_obj, so we need to roll our own.
let vec[ast::obj_field] addtl_fields = [];
alt (anon_obj.fields) {
case (none) { }
case (some(?fields)) { addtl_fields = fields; }
}
let ast::_obj wrapper_obj = rec(
fields = addtl_fields,
methods = anon_obj.methods,
dtor = none[@ast::method]);
auto vtbl = create_vtbl(bcx.fcx.lcx, llself_ty, self_ty, wrapper_obj,
ty_params);
let ast::_obj wrapper_obj =
rec(fields=addtl_fields,
methods=anon_obj.methods,
dtor=none[@ast::method]);
auto vtbl =
create_vtbl(bcx.fcx.lcx, llself_ty, self_ty, wrapper_obj, ty_params);
bcx.build.Store(vtbl, pair_vtbl);
// FIXME (part of issue #417): This vtable needs to contain "forwarding
// slots" for the methods that exist in the with_obj, as well. How do we
@ -6344,29 +6369,28 @@ fn trans_anon_obj(@block_ctxt bcx, &span sp, &ast::anon_obj anon_obj,
// also have to fill in the with_obj field of this tuple.
let TypeRef llbox_ty = T_opaque_obj_ptr(ccx.tn);
alt (anon_obj.fields) {
case (none) {
case (none) {
// If the object we're translating has no fields or type
// parameters, there's not much to do.
// Store null into pair, if no args or typarams.
bcx.build.Store(C_null(llbox_ty), pair_box);
}
case (some(?fields)) {
// For the moment let's pretend that there are no additional
// fields.
bcx.fcx.lcx.ccx.sess.unimpl("anon objs don't support "
+ "adding fields yet");
bcx.fcx.lcx.ccx.sess.unimpl("anon objs don't support " +
"adding fields yet");
// FIXME (issue #417): drop these fields into the newly created
// object.
}
}
// Return the object we built.
ret res(bcx, pair);
}
@ -6824,8 +6848,8 @@ fn ret_ty_of_fn_ty(&@crate_ctxt ccx, ty::t t) -> ty::t {
alt (ty::struct(ccx.tcx, t)) {
case (ty::ty_fn(_, _, ?ret_ty, _, _)) { ret ret_ty; }
case (_) {
ccx.sess.bug("ret_ty_of_fn_ty() called on non-function type: "
+ ty_to_str(ccx.tcx, t));
ccx.sess.bug("ret_ty_of_fn_ty() called on non-function type: " +
ty_to_str(ccx.tcx, t));
}
}
}
@ -6976,10 +7000,10 @@ fn create_vtbl(@local_ctxt cx, TypeRef llself_ty, ty::t self_ty,
let str s = mangle_internal_name_by_path(mcx.ccx, mcx.path);
let ValueRef llfn =
decl_internal_fastcall_fn(cx.ccx.llmod, s, llfnty);
// Every method on an object gets its def_id inserted into the
// crate-wide item_ids map, together with the ValueRef that points to
// where that method's definition will be in the executable.
cx.ccx.item_ids.insert(m.node.id, llfn);
cx.ccx.item_symbols.insert(m.node.id, s);
trans_fn(mcx, m.span, m.node.meth, llfn,
@ -7330,6 +7354,7 @@ fn trans_item(@local_ctxt cx, &ast::item item) {
}
}
// Translate a module. Doing this amounts to translating the items in the
// module; there ends up being no artifact (aside from linkage names) of
// separate modules in the compiled program. That's because modules exist
@ -7587,9 +7612,7 @@ fn decl_native_fn_and_pair(&@crate_ctxt ccx, &span sp, vec[str] path,
finish_fn(fcx, lltop);
}
fn item_path(&@ast::item item) -> vec[str] {
ret [item.ident];
}
fn item_path(&@ast::item item) -> vec[str] { ret [item.ident]; }
fn collect_native_item(@crate_ctxt ccx, &@ast::native_item i, &vec[str] pt,
&vt[vec[str]] v) {

View File

@ -11,23 +11,28 @@ import std::bitv;
*/
type precond = bitv::t;
/* 1 means "this variable must be initialized"
0 means "don't care about this variable" */
type postcond = bitv::t;
/* 1 means "this variable is initialized"
0 means "don't know about this variable */
type prestate = bitv::t;
/* 1 means "this variable must be initialized"
0 means "don't care about this variable" */
type postcond = bitv::t;
/* 1 means "this variable is definitely initialized"
0 means "don't know whether this variable is
initialized" */
type poststate = bitv::t;
/* 1 means "this variable is definitely initialized"
0 means "don't know whether this variable is
initialized" */
/* named thus so as not to confuse with prestate and poststate */
/* 1 means "this variable is initialized"
0 means "don't know about this variable */
type prestate = bitv::t;
/* 1 means "this variable is definitely initialized"
0 means "don't know whether this variable is
initialized" */
type poststate = bitv::t;
/* 1 means "this variable is definitely initialized"
0 means "don't know whether this variable is
initialized" */
/* named thus so as not to confuse with prestate and poststate */
type pre_and_post = @rec(precond precondition, postcond postcondition);

View File

@ -198,9 +198,10 @@ to represent predicate *arguments* however. This type
Both types store an ident and span, for error-logging purposes.
*/
type pred_desc_ = rec(vec[@constr_arg_use] args, uint bit_num);
type pred_desc = spanned[pred_desc_];
type constr_arg_use = constr_arg_general[ident];
type pred_desc = spanned[pred_desc_];
type constr_arg_use = constr_arg_general[ident];
tag constraint {
cinit(uint, span, ident);
@ -512,11 +513,10 @@ fn constraints(&fn_ctxt fcx) -> vec[norm_constraint] {
// FIXME:
// this probably doesn't handle name shadowing well (or at all)
// variables should really always be id'd by def_id and not ident
fn match_args(&fn_ctxt fcx, vec[pred_desc] occs, vec[@constr_arg_use] occ) ->
uint {
log ("match_args: looking at " +
pretty::ppaux::constr_args_to_str(std::util::id[str], occ));
log "match_args: looking at " +
pretty::ppaux::constr_args_to_str(std::util::id[str], occ);
for (pred_desc pd in occs) {
log "match_args: candidate " + pred_desc_to_str(pd);
if (ty::args_eq(str::eq, pd.node.args, occ)) { ret pd.node.bit_num; }
@ -589,13 +589,12 @@ fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr {
fn pred_desc_to_str(&pred_desc p) -> str {
ret "<" + uistr(p.node.bit_num) + ", " +
pretty::ppaux::constr_args_to_str(std::util::id[str], p.node.args)
+ ">";
pretty::ppaux::constr_args_to_str(std::util::id[str], p.node.args)
+ ">";
}
fn substitute_constr_args(&ty::ctxt cx,
&vec[@expr] actuals, &@ty::constr_def c)
-> constr__ {
fn substitute_constr_args(&ty::ctxt cx, &vec[@expr] actuals,
&@ty::constr_def c) -> constr__ {
let vec[@constr_arg_use] res = [];
for (@constr_arg a in c.node.args) {
res += [substitute_arg(cx, actuals, a)];

View File

@ -145,7 +145,8 @@ fn check_states_against_conditions(&fn_ctxt fcx, &_fn f, &ann a) {
if (!promises(fcx, { *post }, ret_c)) {
fcx.ccx.tcx.sess.span_err(f.body.span,
"In non-returning function " + fcx.name
+ ", some control paths may \
+
", some control paths may \
return to the caller");
}
}

View File

@ -102,6 +102,7 @@ fn find_pre_post_item(&crate_ctxt ccx, &item i) {
alt (i.node) {
case (item_const(_, ?e)) {
// make a fake fcx
auto fake_fcx =
rec(enclosing=rec(constrs=@new_def_hash[constraint](),
num_constraints=0u,
@ -113,19 +114,18 @@ fn find_pre_post_item(&crate_ctxt ccx, &item i) {
}
case (item_fn(?f, ?ps)) {
assert (ccx.fm.contains_key(i.id));
auto fcx = rec(enclosing=ccx.fm.get(i.id), id=i.id,
name=i.ident, ccx=ccx);
auto fcx =
rec(enclosing=ccx.fm.get(i.id),
id=i.id,
name=i.ident,
ccx=ccx);
find_pre_post_fn(fcx, f);
}
case (item_mod(?m)) { find_pre_post_mod(m); }
case (item_native_mod(?nm)) {
find_pre_post_native_mod(nm);
}
case (item_native_mod(?nm)) { find_pre_post_native_mod(nm); }
case (item_ty(_, _)) { ret; }
case (item_tag(_, _)) { ret; }
case (item_obj(?o, _, _)) {
find_pre_post_obj(ccx, o);
}
case (item_obj(?o, _, _)) { find_pre_post_obj(ccx, o); }
}
}
@ -254,15 +254,20 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
vec::push[@expr](args, operator);
find_pre_post_exprs(fcx, args, a);
/* see if the call has any constraints on its type */
log("a function: " );
log "a function: ";
log_expr(*operator);
auto pp = expr_pp(fcx.ccx, e);
for (@ty::constr_def c in
constraints_expr(fcx.ccx.tcx, operator)) {
auto i = bit_num(fcx, rec(id=c.node.id,
c=substitute_constr_args(fcx.ccx.tcx, operands, c)));
for (@ty::constr_def c in constraints_expr(fcx.ccx.tcx, operator))
{
auto i =
bit_num(fcx,
rec(id=c.node.id,
c=substitute_constr_args(fcx.ccx.tcx,
operands, c)));
require(i, pp);
}
/* if this is a failing call, its postcondition sets everything */
alt (controlflow_expr(fcx.ccx, operator)) {
case (noreturn) { set_postcond_false(fcx.ccx, a); }
@ -340,6 +345,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
}
case (expr_swap(?lhs, ?rhs, ?a)) {
// Both sides must already be initialized
find_pre_post_exprs(fcx, [lhs, rhs], a);
}
case (expr_assign(?lhs, ?rhs, ?a)) {

View File

@ -361,18 +361,17 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
}
case (expr_swap(?lhs, ?rhs, ?a)) {
/* quite similar to binary -- should abstract this */
changed = extend_prestate_ann(fcx.ccx, a, pres) || changed;
changed = find_pre_post_state_expr(fcx, pres, lhs)
|| changed;
changed = find_pre_post_state_expr(fcx, pres, lhs) || changed;
changed =
find_pre_post_state_expr(fcx,
expr_poststate(fcx.ccx, lhs),
find_pre_post_state_expr(fcx, expr_poststate(fcx.ccx, lhs),
rhs) || changed;
changed =
extend_poststate_ann(fcx.ccx, a,
expr_poststate(fcx.ccx, rhs)) || changed;
ret changed;
}
extend_poststate_ann(fcx.ccx, a, expr_poststate(fcx.ccx, rhs))
|| changed;
ret changed;
}
case (expr_recv(?lhs, ?rhs, ?a)) {
extend_prestate_ann(fcx.ccx, a, pres);
alt (lhs.node) {
@ -502,8 +501,8 @@ fn find_pre_post_state_expr(&fn_ctxt fcx, &prestate pres, @expr e) -> bool {
auto b_post = block_poststate(fcx.ccx, body);
extend_poststate_ann(fcx.ccx, a,
intersect_postconds([e_post,
b_post]))
|| changed
b_post])) ||
changed
};
ret changed;
}

View File

@ -20,7 +20,6 @@ import front::ast::controlflow;
import front::creader;
import middle::metadata;
import util::common::*;
import util::data::interner;
@ -45,14 +44,14 @@ tag any_item {
}
type item_table = hashmap[ast::def_id, any_item];
type constr_table = hashmap[ast::def_id, vec[constr_def]];
type constr_table = hashmap[ast::def_id, vec[constr_def]];
type mt = rec(t ty, ast::mutability mut);
// Contains information needed to resolve types and (in the future) look up
// the types of AST nodes.
type creader_cache = hashmap[tup(int, uint, uint), ty::t];
type ctxt =
@ -61,6 +60,7 @@ type ctxt =
resolve::def_map def_map,
node_type_table node_types,
item_table items, // Only contains type items
constr_table fn_constrs,
type_cache tcache,
creader_cache rcache,
@ -69,12 +69,14 @@ type ctxt =
type ty_ctxt = ctxt;
// Needed for disambiguation from unify::ctxt.
// Convert from method type to function type. Pretty easy; we just drop
// 'ident'.
fn method_ty_to_fn_ty(&ctxt cx, method m) -> t {
ret mk_fn(cx, m.proto, m.inputs, m.output, m.cf, m.constrs);
}
// Needed for disambiguation from unify::ctxt.
// Convert from method type to function type. Pretty easy; we just drop
// 'ident'.
fn method_ty_to_fn_ty(&ctxt cx, method m) -> t {
ret mk_fn(cx, m.proto, m.inputs, m.output, m.cf, m.constrs);
}
// Never construct these manually. These are interned.
//
@ -127,9 +129,10 @@ tag sty {
}
type constr_def = spanned[constr_general[uint]];
type constr_general[T] = rec(path path,
vec[@constr_arg_general[T]] args,
def_id id);
type constr_general[T] =
rec(path path, vec[@constr_arg_general[T]] args, def_id id);
// Data structures used in type unification
tag type_err {
@ -244,7 +247,6 @@ fn mk_rcache() -> creader_cache {
}
fn mk_ctxt(session::session s, resolve::def_map dm, constr_table cs) -> ctxt {
let vec[mutable option::t[ty::ty_param_substs_opt_and_ty]] ntt_sub =
[mutable ];
let node_type_table ntt = @mutable ntt_sub;
@ -257,7 +259,7 @@ fn mk_ctxt(session::session s, resolve::def_map dm, constr_table cs) -> ctxt {
def_map=dm,
node_types=ntt,
items=items,
fn_constrs = cs,
fn_constrs=cs,
tcache=tcache,
rcache=mk_rcache(),
short_names_cache=map::mk_hashmap[ty::t,
@ -1113,7 +1115,7 @@ fn args_eq[T](fn(&T, &T) -> bool eq, vec[@ast::constr_arg_general[T]] a,
fn constr_eq(&@constr_def c, &@constr_def d) -> bool {
ret path_to_str(c.node.path) == path_to_str(d.node.path) &&
// FIXME: hack
// FIXME: hack
args_eq(eq_int, c.node.args, d.node.args);
}
@ -1529,7 +1531,7 @@ fn expr_ann(&@ast::expr e) -> ast::ann {
case (ast::expr_block(_, ?a)) { ret a; }
case (ast::expr_move(_, _, ?a)) { ret a; }
case (ast::expr_assign(_, _, ?a)) { ret a; }
case (ast::expr_swap(_,_,?a)) { ret a; }
case (ast::expr_swap(_, _, ?a)) { ret a; }
case (ast::expr_assign_op(_, _, _, ?a)) { ret a; }
case (ast::expr_send(_, _, ?a)) { ret a; }
case (ast::expr_recv(_, _, ?a)) { ret a; }

View File

@ -103,10 +103,7 @@ fn walk_item(&ast_visitor v, @ast::item i) {
if (!v.keep_going()) { ret; }
v.visit_item_pre(i);
alt (i.node) {
case (ast::item_const(?t, ?e)) {
walk_ty(v, t);
walk_expr(v, e);
}
case (ast::item_const(?t, ?e)) { walk_ty(v, t); walk_expr(v, e); }
case (ast::item_fn(?f, _)) {
walk_fn(v, f, i.span, i.ident, i.id, i.ann);
}

View File

@ -208,9 +208,8 @@ obj printer(io::writer out,
mutable uint right, // index of right side of input stream
mutable vec[mutable token]
token, // ring-buffr stream goes through
mutable vec[mutable token] token,
// ring-buffr stream goes through
mutable vec[mutable int] size, // ring-buffer of calculated sizes
mutable int left_total, // running size of stream "...left"

View File

@ -20,7 +20,6 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
};
ret s + ty_to_str(cx, input.ty);
}
fn fn_to_str(&ctxt cx, ast::proto proto, option::t[ast::ident] ident,
vec[arg] inputs, t output, ast::controlflow cf,
&vec[@constr_def] constrs) -> str {
@ -92,8 +91,8 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
}
case (ty_tag(?id, ?tps)) {
// The user should never see this if the cname is set properly!
s +=
"<tag#" + istr(id._0) + ":" + istr(id._1) + ">";
s += "<tag#" + istr(id._0) + ":" + istr(id._1) + ">";
if (vec::len[t](tps) > 0u) {
auto f = bind ty_to_str(cx, _);
auto strs = vec::map[t, str](f, tps);
@ -101,9 +100,7 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
}
}
case (ty_fn(?proto, ?inputs, ?output, ?cf, ?constrs)) {
s +=
fn_to_str(cx, proto, none, inputs, output, cf,
constrs);
s += fn_to_str(cx, proto, none, inputs, output, cf, constrs);
}
case (ty_native_fn(_, ?inputs, ?output)) {
s +=
@ -346,18 +343,16 @@ const uint default_columns = 78u;
// needed b/c constr_args_to_str needs
// something that takes an alias
// (argh)
fn uint_to_str(&uint i) -> str { ret uistr(i); }
fn constr_to_str(&@constr_def c) -> str {
ret path_to_str(c.node.path)
+ constr_args_to_str(uint_to_str, c.node.args);
ret path_to_str(c.node.path) +
constr_args_to_str(uint_to_str, c.node.args);
}
fn ast_constr_to_str(&@front::ast::constr c) -> str {
ret path_to_str(c.node.path)
+ constr_args_to_str(uint_to_str, c.node.args);
ret path_to_str(c.node.path) +
constr_args_to_str(uint_to_str, c.node.args);
}
fn constrs_str(&vec[@constr_def] constrs) -> str {
@ -371,21 +366,14 @@ fn constrs_str(&vec[@constr_def] constrs) -> str {
}
fn ast_constrs_str(&vec[@ast::constr] constrs) -> str {
auto s = "";
auto colon = true;
for (@ast::constr c in constrs) {
if (colon) {
s += " : ";
colon = false;
auto s = "";
auto colon = true;
for (@ast::constr c in constrs) {
if (colon) { s += " : "; colon = false; } else { s += ", "; }
s += ast_constr_to_str(c);
}
else {
s += ", ";
}
s += ast_constr_to_str(c);
}
ret s;
ret s;
}
//
// Local Variables:
// mode: rust

View File

@ -1,17 +1,15 @@
import option;
import option::some;
import option::none;
tag t[T, U] {
left(T);
right(U);
}
tag t[T, U] { left(T); right(U); }
type operator[T, U] = fn(&T) -> U;
type operator[T, U] = fn(&T) -> U ;
fn either[T, U, V](&operator[T, V] f_left,
&operator[U, V] f_right,
&t[T, U] value) -> V {
fn either[T, U,
V](&operator[T, V] f_left, &operator[U, V] f_right, &t[T, U] value)
-> V {
alt (value) {
case (left(?l)) { f_left(l) }
case (right(?r)) { f_right(r) }
@ -23,7 +21,7 @@ fn lefts[T, U](&vec[t[T, U]] eithers) -> vec[T] {
for (t[T, U] elt in eithers) {
alt (elt) {
case (left(?l)) { result += [l] }
case (_) { /* fallthrough */ }
case (_) {/* fallthrough */ }
}
}
ret result;
@ -34,7 +32,7 @@ fn rights[T, U](&vec[t[T, U]] eithers) -> vec[U] {
for (t[T, U] elt in eithers) {
alt (elt) {
case (right(?r)) { result += [r] }
case (_) { /* fallthrough */ }
case (_) {/* fallthrough */ }
}
}
ret result;
@ -51,7 +49,6 @@ fn partition[T, U](&vec[t[T, U]] eithers) -> tup(vec[T], vec[U]) {
}
ret tup(lefts, rights);
}
//
// Local Variables:
// mode: rust

View File

@ -33,7 +33,8 @@ fn basename(path p) -> path {
fn connect(path pre, path post) -> path {
auto len = str::byte_len(pre);
ret if (pre.(len - 1u) == os_fs::path_sep as u8) {
// Trailing '/'?
// Trailing '/'?
pre + post
} else { pre + path_sep() + post };
}

View File

@ -23,10 +23,7 @@ fn foldl[T, U](&list[T] ls_, &U u, fn(&T, &U) -> U f) -> U {
auto ls = ls_;
while (true) {
alt (ls) {
case (cons(?hd, ?tl)) {
accum = f(hd, accum);
ls = *tl;
}
case (cons(?hd, ?tl)) { accum = f(hd, accum); ls = *tl; }
case (nil) { break; }
}
}
@ -54,16 +51,13 @@ fn has[T](&list[T] ls_, &T elt) -> bool {
while (true) {
alt (ls) {
case (cons(?hd, ?tl)) {
if (elt == hd) {
ret true;
} else {
ls = *tl;
}
if (elt == hd) { ret true; } else { ls = *tl; }
}
case (nil) { ret false; }
}
}
ret false; // Typestate checker doesn't understand infinite loops
}
fn length[T](&list[T] ls) -> uint {

View File

@ -48,17 +48,11 @@ fn reset(io::buf_writer writer) {
}
fn color_supported() -> bool {
auto supported_terms = ["xterm-color",
"xterm",
"screen-bce"];
auto supported_terms = ["xterm-color", "xterm", "screen-bce"];
ret alt (generic_os::getenv("TERM")) {
case (option::some(?env)) {
vec::member(env, supported_terms)
}
case (option::none) {
false
}
};
case (option::some(?env)) { vec::member(env, supported_terms) }
case (option::none) { false }
};
}
fn set_color(io::buf_writer writer, u8 first_char, u8 color) {

View File

@ -7,7 +7,8 @@ fn id[T](&T x) -> T { ret x; }
* the constraint once fixed. */
type rational = rec(int num, int den);
// : int::positive(*.den);
// : int::positive(*.den);
fn rational_leq(&rational x, &rational y) -> bool {
// NB: Uses the fact that rationals have positive denominators WLOG: