Reformat a bunch of recent churn.
This commit is contained in:
parent
eb9969f546
commit
b84fffaa4e
@ -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;
|
||||
|
||||
|
@ -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),
|
||||
|
@ -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";
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
||||
|
@ -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)];
|
||||
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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 };
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -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) {
|
||||
|
@ -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:
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user