1
Fork 0

rustc: Revert the conversion to interior vectors due to heap corruption

This commit is contained in:
Patrick Walton 2011-07-06 11:26:26 -07:00
parent ec890fff23
commit bbdba21b1f
27 changed files with 629 additions and 774 deletions

View file

@ -1,6 +1,5 @@
// Functions dealing with attributes and meta_items // Functions dealing with attributes and meta_items
import std::ivec;
import std::vec; import std::vec;
import std::str; import std::str;
import std::map; import std::map;
@ -29,11 +28,13 @@ export mk_attr;
// From a list of crate attributes get only the meta_items that impact crate // From a list of crate attributes get only the meta_items that impact crate
// linkage // linkage
fn find_linkage_metas(&ast::attribute[] attrs) -> (@ast::meta_item)[] { fn find_linkage_metas(vec[ast::attribute] attrs) -> vec[@ast::meta_item] {
let (@ast::meta_item)[] metas = ~[]; let vec[@ast::meta_item] metas = [];
for (ast::attribute attr in find_attrs_by_name(attrs, "link")) { for (ast::attribute attr in find_attrs_by_name(attrs, "link")) {
alt (attr.node.value.node) { alt (attr.node.value.node) {
case (ast::meta_list(_, ?items)) { metas += items; } case (ast::meta_list(_, ?items)) {
metas += items;
}
case (_) { case (_) {
log "ignoring link attribute that has incorrect type"; log "ignoring link attribute that has incorrect type";
} }
@ -43,8 +44,8 @@ fn find_linkage_metas(&ast::attribute[] attrs) -> (@ast::meta_item)[] {
} }
// Search a list of attributes and return only those with a specific name // Search a list of attributes and return only those with a specific name
fn find_attrs_by_name(&ast::attribute[] attrs, fn find_attrs_by_name(vec[ast::attribute] attrs,
ast::ident name) -> ast::attribute[] { ast::ident name) -> vec[ast::attribute] {
auto filter = bind fn(&ast::attribute a, auto filter = bind fn(&ast::attribute a,
ast::ident name) -> option::t[ast::attribute] { ast::ident name) -> option::t[ast::attribute] {
if (get_attr_name(a) == name) { if (get_attr_name(a) == name) {
@ -53,7 +54,7 @@ fn find_attrs_by_name(&ast::attribute[] attrs,
option::none option::none
} }
} (_, name); } (_, name);
ret ivec::filter_map(filter, attrs); ret vec::filter_map(filter, attrs);
} }
fn get_attr_name(&ast::attribute attr) -> ast::ident { fn get_attr_name(&ast::attribute attr) -> ast::ident {
@ -100,10 +101,8 @@ fn get_meta_item_value_str(&@ast::meta_item meta) -> option::t[str] {
fn attr_meta(&ast::attribute attr) -> @ast::meta_item { @attr.node.value } fn attr_meta(&ast::attribute attr) -> @ast::meta_item { @attr.node.value }
// Get the meta_items from inside a vector of attributes // Get the meta_items from inside a vector of attributes
fn attr_metas(&ast::attribute[] attrs) -> vec[@ast::meta_item] { fn attr_metas(&vec[ast::attribute] attrs) -> vec[@ast::meta_item] {
auto mitems = []; ret vec::map(attr_meta, attrs);
for (ast::attribute a in attrs) { mitems += [attr_meta(a)]; }
ret mitems;
} }
fn eq(@ast::meta_item a, @ast::meta_item b) -> bool { fn eq(@ast::meta_item a, @ast::meta_item b) -> bool {
@ -131,7 +130,7 @@ fn eq(@ast::meta_item a, @ast::meta_item b) -> bool {
} }
} }
fn contains(&(@ast::meta_item)[] haystack, @ast::meta_item needle) -> bool { fn contains(&vec[@ast::meta_item] haystack, @ast::meta_item needle) -> bool {
log #fmt("looking for %s", log #fmt("looking for %s",
syntax::print::pprust::meta_item_to_str(*needle)); syntax::print::pprust::meta_item_to_str(*needle));
for (@ast::meta_item item in haystack) { for (@ast::meta_item item in haystack) {
@ -220,8 +219,8 @@ fn mk_name_value_item(ast::ident name, ast::lit value) -> @ast::meta_item {
ret @span(ast::meta_name_value(name, value)); ret @span(ast::meta_name_value(name, value));
} }
fn mk_list_item(ast::ident name, &(@ast::meta_item)[] items) fn mk_list_item(ast::ident name,
-> @ast::meta_item { &vec[@ast::meta_item] items) -> @ast::meta_item {
ret @span(ast::meta_list(name, items)); ret @span(ast::meta_list(name, items));
} }

View file

@ -1,4 +1,3 @@
import std::ivec;
import std::option; import std::option;
import std::vec; import std::vec;
import syntax::ast; import syntax::ast;
@ -98,20 +97,20 @@ fn native_item_in_cfg(&ast::crate_cfg cfg, &@ast::native_item item) -> bool {
// Determine if an item should be translated in the current crate // Determine if an item should be translated in the current crate
// configuration based on the item's attributes // configuration based on the item's attributes
fn in_cfg(&ast::crate_cfg cfg, &ast::attribute[] attrs) -> bool { fn in_cfg(&ast::crate_cfg cfg, &vec[ast::attribute] attrs) -> bool {
// The "cfg" attributes on the item // The "cfg" attributes on the item
auto item_cfg_attrs = attr::find_attrs_by_name(attrs, "cfg"); auto item_cfg_attrs = attr::find_attrs_by_name(attrs, "cfg");
auto item_has_cfg_attrs = ivec::len(item_cfg_attrs) > 0u; auto item_has_cfg_attrs = vec::len(item_cfg_attrs) > 0u;
if (!item_has_cfg_attrs) { ret true; } if (!item_has_cfg_attrs) { ret true; }
// Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes, // Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes,
// so we can match against them. This is the list of configurations for // so we can match against them. This is the list of configurations for
// which the item is valid // which the item is valid
auto item_cfg_metas = { auto item_cfg_metas = {
fn extract_metas(&(@ast::meta_item)[] inner_items, fn extract_metas(&vec[@ast::meta_item] inner_items,
&@ast::meta_item cfg_item) &@ast::meta_item cfg_item)
-> (@ast::meta_item)[] { -> vec[@ast::meta_item] {
alt (cfg_item.node) { alt (cfg_item.node) {
case (ast::meta_list(?name, ?items)) { case (ast::meta_list(?name, ?items)) {
@ -122,11 +121,13 @@ fn in_cfg(&ast::crate_cfg cfg, &ast::attribute[] attrs) -> bool {
} }
} }
auto cfg_metas = attr::attr_metas(item_cfg_attrs); auto cfg_metas = attr::attr_metas(item_cfg_attrs);
ivec::foldl(extract_metas, ~[], cfg_metas) vec::foldl(extract_metas, [], cfg_metas)
}; };
for (@ast::meta_item cfg_mi in item_cfg_metas) { for (@ast::meta_item cfg_mi in item_cfg_metas) {
if (attr::contains(cfg, cfg_mi)) { ret true; } if (attr::contains(cfg, cfg_mi)) {
ret true;
}
} }
ret false; ret false;

View file

@ -194,27 +194,27 @@ fn get_symbol(session::session sess, ast::def_id def) -> str {
ret item_symbol(lookup_item(def._1, data)); ret item_symbol(lookup_item(def._1, data));
} }
fn get_tag_variants(ty::ctxt tcx, ast::def_id def) -> ty::variant_info[] { fn get_tag_variants(ty::ctxt tcx, ast::def_id def) -> vec[ty::variant_info] {
auto external_crate_id = def._0; auto external_crate_id = def._0;
auto data = tcx.sess.get_external_crate(external_crate_id).data; auto data = tcx.sess.get_external_crate(external_crate_id).data;
auto items = ebml::get_doc(ebml::new_doc(data), tag_items); auto items = ebml::get_doc(ebml::new_doc(data), tag_items);
auto item = find_item(def._1, items); auto item = find_item(def._1, items);
let ty::variant_info[] infos = ~[]; let vec[ty::variant_info] infos = [];
auto variant_ids = tag_variant_ids(item, external_crate_id); auto variant_ids = tag_variant_ids(item, external_crate_id);
for (ast::def_id did in variant_ids) { for (ast::def_id did in variant_ids) {
auto item = find_item(did._1, items); auto item = find_item(did._1, items);
auto ctor_ty = item_type(item, external_crate_id, tcx); auto ctor_ty = item_type(item, external_crate_id, tcx);
let ty::t[] arg_tys = ~[]; let vec[ty::t] arg_tys = [];
alt (ty::struct(tcx, ctor_ty)) { alt (ty::struct(tcx, ctor_ty)) {
case (ty::ty_fn(_, ?args, _, _, _)) { case (ty::ty_fn(_, ?args, _, _, _)) {
for (ty::arg a in args) { arg_tys += ~[a.ty]; } for (ty::arg a in args) { arg_tys += [a.ty]; }
} }
case (_) { case (_) {
// Nullary tag variant. // Nullary tag variant.
} }
} }
infos += ~[rec(args=arg_tys, ctor_ty=ctor_ty, id=did)]; infos += [rec(args=arg_tys, ctor_ty=ctor_ty, id=did)];
} }
ret infos; ret infos;
} }
@ -290,8 +290,8 @@ fn get_meta_items(&ebml::doc md) -> vec[@ast::meta_item] {
ret items; ret items;
} }
fn get_attributes(&ebml::doc md) -> ast::attribute[] { fn get_attributes(&ebml::doc md) -> vec[ast::attribute] {
let ast::attribute[] attrs = ~[]; let vec[ast::attribute] attrs = [];
alt (ebml::maybe_get_doc(md, tag_attributes)) { alt (ebml::maybe_get_doc(md, tag_attributes)) {
case (option::some(?attrs_d)) { case (option::some(?attrs_d)) {
for each (ebml::doc attr_doc in for each (ebml::doc attr_doc in
@ -301,9 +301,9 @@ fn get_attributes(&ebml::doc md) -> ast::attribute[] {
// an attribute // an attribute
assert (vec::len(meta_items) == 1u); assert (vec::len(meta_items) == 1u);
auto meta_item = meta_items.(0); auto meta_item = meta_items.(0);
attrs += ~[rec(node=rec(style=ast::attr_outer, attrs += [rec(node=rec(style=ast::attr_outer,
value=*meta_item), value=*meta_item),
span=rec(lo=0u, hi=0u))]; span=rec(lo=0u, hi=0u))];
} }
} }
case (option::none) { } case (option::none) { }
@ -327,7 +327,7 @@ fn list_crate_attributes(&ebml::doc md, io::writer out) {
out.write_str("\n\n"); out.write_str("\n\n");
} }
fn get_crate_attributes(&vec[u8] data) -> ast::attribute[] { fn get_crate_attributes(&vec[u8] data) -> vec[ast::attribute] {
ret get_attributes(ebml::new_doc(data)); ret get_attributes(ebml::new_doc(data));
} }

View file

@ -65,13 +65,13 @@ fn parse_ty_or_bang(@pstate st, str_def sd) -> ty_or_bang {
} }
} }
fn parse_constrs(@pstate st, str_def sd) -> (@ty::constr_def)[] { fn parse_constrs(@pstate st, str_def sd) -> vec[@ty::constr_def] {
let (@ty::constr_def)[] rslt = ~[]; let vec[@ty::constr_def] rslt = [];
alt (peek(st) as char) { alt (peek(st) as char) {
case (':') { case (':') {
do { do {
next(st); next(st);
rslt += ~[parse_constr(st, sd)]; vec::push(rslt, parse_constr(st, sd));
} while (peek(st) as char == ';') } while (peek(st) as char == ';')
} }
case (_) { } case (_) { }
@ -80,21 +80,21 @@ fn parse_constrs(@pstate st, str_def sd) -> (@ty::constr_def)[] {
} }
fn parse_path(@pstate st, str_def sd) -> ast::path { fn parse_path(@pstate st, str_def sd) -> ast::path {
let ast::ident[] idents = ~[]; let vec[ast::ident] idents = [];
fn is_last(char c) -> bool { fn is_last(char c) -> bool {
ret (c == '(' || c == ':'); ret (c == '(' || c == ':');
} }
idents += ~[parse_ident_(st, sd, is_last)]; idents += [parse_ident_(st, sd, is_last)];
while (true) { while (true) {
alt (peek(st) as char) { alt (peek(st) as char) {
case (':') { next(st); next(st); } case (':') { next(st); next(st); }
case (?c) { case (?c) {
if (c == '(') { if (c == '(') {
ret respan(rec(lo=0u, hi=0u), ret respan(rec(lo=0u, hi=0u),
rec(idents=idents, types=~[])); rec(idents=idents, types=[]));
} }
else { else {
idents += ~[parse_ident_(st, sd, is_last)]; idents += [parse_ident_(st, sd, is_last)];
} }
} }
} }
@ -103,7 +103,7 @@ fn parse_path(@pstate st, str_def sd) -> ast::path {
} }
fn parse_constr(@pstate st, str_def sd) -> @ty::constr_def { fn parse_constr(@pstate st, str_def sd) -> @ty::constr_def {
let (@ast::constr_arg)[] args = ~[]; let vec[@ast::constr_arg] args = [];
auto sp = rec(lo=0u,hi=0u); // FIXME: use a real span auto sp = rec(lo=0u,hi=0u); // FIXME: use a real span
let ast::path pth = parse_path(st, sd); let ast::path pth = parse_path(st, sd);
let char ignore = next(st) as char; let char ignore = next(st) as char;
@ -113,15 +113,14 @@ fn parse_constr(@pstate st, str_def sd) -> @ty::constr_def {
alt (peek(st) as char) { alt (peek(st) as char) {
case ('*') { case ('*') {
st.pos += 1u; st.pos += 1u;
args += ~[@respan(sp, ast::carg_base)]; args += [@respan(sp, ast::carg_base)];
} }
case (?c) { case (?c) {
/* how will we disambiguate between /* how will we disambiguate between
an arg index and a lit argument? */ an arg index and a lit argument? */
if (c >= '0' && c <= '9') { if (c >= '0' && c <= '9') {
// FIXME // FIXME
args += ~[@respan(sp, args += [@respan(sp, ast::carg_ident((c as uint) - 48u))];
ast::carg_ident((c as uint) - 48u))];
ignore = next(st) as char; ignore = next(st) as char;
} }
else { else {
@ -170,8 +169,8 @@ fn parse_ty(@pstate st, str_def sd) -> ty::t {
case ('t') { case ('t') {
assert (next(st) as char == '['); assert (next(st) as char == '[');
auto def = parse_def(st, sd); auto def = parse_def(st, sd);
let ty::t[] params = ~[]; let vec[ty::t] params = [];
while (peek(st) as char != ']') { params += ~[parse_ty(st, sd)]; } while (peek(st) as char != ']') { params += [parse_ty(st, sd)]; }
st.pos = st.pos + 1u; st.pos = st.pos + 1u;
ret ty::mk_tag(st.tcx, def, params); ret ty::mk_tag(st.tcx, def, params);
} }
@ -227,7 +226,7 @@ fn parse_ty(@pstate st, str_def sd) -> ty::t {
} }
case ('O') { case ('O') {
assert (next(st) as char == '['); assert (next(st) as char == '[');
let ty::method[] methods = ~[]; let vec[ty::method] methods = [];
while (peek(st) as char != ']') { while (peek(st) as char != ']') {
auto proto; auto proto;
alt (next(st) as char) { alt (next(st) as char) {
@ -240,12 +239,12 @@ fn parse_ty(@pstate st, str_def sd) -> ty::t {
} }
auto func = parse_ty_fn(st, sd); auto func = parse_ty_fn(st, sd);
methods += methods +=
~[rec(proto=proto, [rec(proto=proto,
ident=name, ident=name,
inputs=func._0, inputs=func._0,
output=func._1, output=func._1,
cf=func._2, cf=func._2,
constrs=func._3)]; constrs=func._3)];
} }
st.pos += 1u; st.pos += 1u;
ret ty::mk_obj(st.tcx, methods); ret ty::mk_obj(st.tcx, methods);
@ -254,8 +253,8 @@ fn parse_ty(@pstate st, str_def sd) -> ty::t {
assert (next(st) as char == '['); assert (next(st) as char == '[');
auto def = parse_def(st, sd); auto def = parse_def(st, sd);
auto inner = parse_ty(st, sd); auto inner = parse_ty(st, sd);
let ty::t[] params = ~[]; let vec[ty::t] params = [];
while (peek(st) as char != ']') { params += ~[parse_ty(st, sd)]; } while (peek(st) as char != ']') { params += [parse_ty(st, sd)]; }
st.pos = st.pos + 1u; st.pos = st.pos + 1u;
ret ty::mk_res(st.tcx, def, inner, params); ret ty::mk_res(st.tcx, def, inner, params);
} }
@ -334,7 +333,7 @@ fn parse_hex(@pstate st) -> uint {
} }
fn parse_ty_fn(@pstate st, str_def sd) -> fn parse_ty_fn(@pstate st, str_def sd) ->
tup(ty::arg[], ty::t, ast::controlflow, (@ty::constr_def)[]) { tup(ty::arg[], ty::t, ast::controlflow, vec[@ty::constr_def]) {
assert (next(st) as char == '['); assert (next(st) as char == '[');
let ty::arg[] inputs = ~[]; let ty::arg[] inputs = ~[];
while (peek(st) as char != ']') { while (peek(st) as char != ']') {

View file

@ -162,7 +162,7 @@ fn enc_sty(&io::writer w, &@ctxt cx, &ty::sty st) {
case (native_abi_cdecl) { w.write_char('c'); } case (native_abi_cdecl) { w.write_char('c'); }
case (native_abi_llvm) { w.write_char('l'); } case (native_abi_llvm) { w.write_char('l'); }
} }
enc_ty_fn(w, cx, args, out, return, ~[]); enc_ty_fn(w, cx, args, out, return, []);
} }
case (ty::ty_obj(?methods)) { case (ty::ty_obj(?methods)) {
w.write_str("O["); w.write_str("O[");
@ -205,7 +205,7 @@ fn enc_proto(&io::writer w, proto proto) {
} }
} }
fn enc_ty_fn(&io::writer w, &@ctxt cx, &ty::arg[] args, &ty::t out, fn enc_ty_fn(&io::writer w, &@ctxt cx, &ty::arg[] args, &ty::t out,
&controlflow cf, &(@ty::constr_def)[] constrs) { &controlflow cf, &vec[@ty::constr_def] constrs) {
w.write_char('['); w.write_char('[');
for (ty::arg arg in args) { for (ty::arg arg in args) {
alt (arg.mode) { alt (arg.mode) {

View file

@ -18,7 +18,6 @@ import syntax::ast::respan;
import middle::ty::constr_table; import middle::ty::constr_table;
import syntax::visit; import syntax::visit;
import visit::vt; import visit::vt;
import std::ivec;
import std::map::hashmap; import std::map::hashmap;
import std::list; import std::list;
import std::list::list; import std::list::list;
@ -139,7 +138,7 @@ fn resolve_crate(session sess, &ast_map::map amap, @ast::crate crate) ->
auto e = auto e =
@rec(crate_map=new_int_hash[ast::crate_num](), @rec(crate_map=new_int_hash[ast::crate_num](),
def_map=new_int_hash[def](), def_map=new_int_hash[def](),
fn_constrs = new_int_hash[ty::constr_def[]](), fn_constrs = new_int_hash[vec[ty::constr_def]](),
ast_map=amap, ast_map=amap,
imports=new_int_hash[import_state](), imports=new_int_hash[import_state](),
mod_map=new_int_hash[@indexed_mod](), mod_map=new_int_hash[@indexed_mod](),
@ -417,14 +416,8 @@ fn resolve_constr(@env e, node_id id, &@ast::constr c, &scopes sc,
if (option::is_some(new_def)) { if (option::is_some(new_def)) {
alt (option::get(new_def)) { alt (option::get(new_def)) {
case (ast::def_fn(?pred_id, ast::pure_fn)) { case (ast::def_fn(?pred_id, ast::pure_fn)) {
// FIXME: Remove this vec->ivec conversion.
let (@ast::constr_arg_general[uint])[] cag_ivec = ~[];
for (@ast::constr_arg_general[uint] cag in c.node.args) {
cag_ivec += ~[cag];
}
let ty::constr_general[uint] c_ = let ty::constr_general[uint] c_ =
rec(path=c.node.path, args=cag_ivec, id=pred_id); rec(path=c.node.path, args=c.node.args, id=pred_id);
let ty::constr_def new_constr = respan(c.span, c_); let ty::constr_def new_constr = respan(c.span, c_);
add_constr(e, id, new_constr); add_constr(e, id, new_constr);
} }
@ -440,8 +433,8 @@ fn resolve_constr(@env e, node_id id, &@ast::constr c, &scopes sc,
fn add_constr(&@env e, node_id id, &ty::constr_def c) { fn add_constr(&@env e, node_id id, &ty::constr_def c) {
e.fn_constrs.insert(id, e.fn_constrs.insert(id,
alt (e.fn_constrs.find(id)) { alt (e.fn_constrs.find(id)) {
case (none) { ~[c] } case (none) { [c] }
case (some(?cs)) { cs + ~[c] } case (some(?cs)) { cs + [c] }
}); });
} }
@ -555,9 +548,9 @@ fn mk_unresolved_msg(&ident id, &str kind) -> str {
} }
// Lookup helpers // Lookup helpers
fn lookup_path_strict(&env e, &scopes sc, &span sp, &ident[] idents, fn lookup_path_strict(&env e, &scopes sc, &span sp, vec[ident] idents,
namespace ns) -> option::t[def] { namespace ns) -> option::t[def] {
auto n_idents = ivec::len(idents); auto n_idents = vec::len(idents);
auto headns = if (n_idents == 1u) { ns } else { ns_module }; auto headns = if (n_idents == 1u) { ns } else { ns_module };
auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), headns); auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), headns);
auto i = 1u; auto i = 1u;

View file

@ -879,11 +879,7 @@ fn type_of_inner(&@crate_ctxt cx, &span sp, &ty::t t) -> TypeRef {
llty = abs_pair; llty = abs_pair;
} }
case (ty::ty_res(_, ?sub, ?tps)) { case (ty::ty_res(_, ?sub, ?tps)) {
// FIXME: Remove this vec->ivec conversion. auto sub1 = ty::substitute_type_params(cx.tcx, tps, sub);
auto tps_ivec = ~[];
for (ty::t typ in tps) { tps_ivec += ~[typ]; }
auto sub1 = ty::substitute_type_params(cx.tcx, tps_ivec, sub);
ret T_struct([T_i32(), type_of_inner(cx, sp, sub1)]); ret T_struct([T_i32(), type_of_inner(cx, sp, sub1)]);
} }
case (ty::ty_var(_)) { case (ty::ty_var(_)) {
@ -903,7 +899,7 @@ fn type_of_inner(&@crate_ctxt cx, &span sp, &ty::t t) -> TypeRef {
fn type_of_tag(&@crate_ctxt cx, &span sp, &ast::def_id did, &ty::t t) fn type_of_tag(&@crate_ctxt cx, &span sp, &ast::def_id did, &ty::t t)
-> TypeRef { -> TypeRef {
auto degen = std::ivec::len(ty::tag_variants(cx.tcx, did)) == 1u; auto degen = vec::len(ty::tag_variants(cx.tcx, did)) == 1u;
if (ty::type_has_dynamic_size(cx.tcx, t)) { if (ty::type_has_dynamic_size(cx.tcx, t)) {
if (degen) { ret T_i8(); } if (degen) { ret T_i8(); }
else { ret T_opaque_tag(cx.tn); } else { ret T_opaque_tag(cx.tn); }
@ -1244,12 +1240,7 @@ fn simplify_type(&@crate_ctxt ccx, &ty::t typ) -> ty::t {
ty::mk_nil(ccx.tcx))]); ty::mk_nil(ccx.tcx))]);
} }
case (ty::ty_res(_, ?sub, ?tps)) { case (ty::ty_res(_, ?sub, ?tps)) {
// FIXME: Remove this vec->ivec conversion. auto sub1 = ty::substitute_type_params(ccx.tcx, tps, sub);
auto tps_ivec = ~[];
for (ty::t typ in tps) { tps_ivec += ~[typ]; }
auto sub1 = ty::substitute_type_params(ccx.tcx, tps_ivec,
sub);
ret ty::mk_imm_tup(ccx.tcx, ~[ty::mk_int(ccx.tcx), ret ty::mk_imm_tup(ccx.tcx, ~[ty::mk_int(ccx.tcx),
simplify_type(ccx, sub1)]); simplify_type(ccx, sub1)]);
} }
@ -1268,35 +1259,36 @@ fn static_size_of_tag(&@crate_ctxt cx, &span sp, &ty::t t) -> uint {
"static_size_of_tag()"); "static_size_of_tag()");
} }
if (cx.tag_sizes.contains_key(t)) { ret cx.tag_sizes.get(t); } if (cx.tag_sizes.contains_key(t)) { ret cx.tag_sizes.get(t); }
auto tid;
let vec[ty::t] subtys;
alt (ty::struct(cx.tcx, t)) { alt (ty::struct(cx.tcx, t)) {
case (ty::ty_tag(?tid, ?subtys)) { case (ty::ty_tag(?tid_, ?subtys_)) { tid = tid_; subtys = subtys_; }
// Compute max(variant sizes).
auto max_size = 0u;
auto variants = ty::tag_variants(cx.tcx, tid);
for (ty::variant_info variant in variants) {
// TODO: Remove this vec->ivec conversion.
auto args = ~[];
for (ty::t typ in variant.args) { args += ~[typ]; }
auto tup_ty = simplify_type(cx, ty::mk_imm_tup(cx.tcx, args));
// Perform any type parameter substitutions.
tup_ty = ty::substitute_type_params(cx.tcx, subtys, tup_ty);
// Here we possibly do a recursive call.
auto this_size = llsize_of_real(cx, type_of(cx, sp, tup_ty));
if (max_size < this_size) { max_size = this_size; }
}
cx.tag_sizes.insert(t, max_size);
ret max_size;
}
case (_) { case (_) {
cx.tcx.sess.span_fatal(sp, cx.tcx.sess.span_fatal(sp,
"non-tag passed to " + "non-tag passed to " +
"static_size_of_tag()"); "static_size_of_tag()");
} }
} }
// Compute max(variant sizes).
auto max_size = 0u;
auto variants = ty::tag_variants(cx.tcx, tid);
for (ty::variant_info variant in variants) {
// TODO: Remove this vec->ivec conversion.
auto args = ~[];
for (ty::t typ in variant.args) { args += ~[typ]; }
auto tup_ty = simplify_type(cx, ty::mk_imm_tup(cx.tcx, args));
// Perform any type parameter substitutions.
tup_ty = ty::substitute_type_params(cx.tcx, subtys, tup_ty);
// Here we possibly do a recursive call.
auto this_size = llsize_of_real(cx, type_of(cx, sp, tup_ty));
if (max_size < this_size) { max_size = this_size; }
}
cx.tag_sizes.insert(t, max_size);
ret max_size;
} }
fn dynamic_size_of(&@block_ctxt cx, ty::t t) -> result { fn dynamic_size_of(&@block_ctxt cx, ty::t t) -> result {
@ -1351,7 +1343,7 @@ fn dynamic_size_of(&@block_ctxt cx, ty::t t) -> result {
for (ty::variant_info variant in variants) { for (ty::variant_info variant in variants) {
// Perform type substitution on the raw argument types. // Perform type substitution on the raw argument types.
let ty::t[] raw_tys = variant.args; let vec[ty::t] raw_tys = variant.args;
let vec[ty::t] tys = []; let vec[ty::t] tys = [];
for (ty::t raw_ty in raw_tys) { for (ty::t raw_ty in raw_tys) {
auto t = auto t =
@ -1366,7 +1358,7 @@ fn dynamic_size_of(&@block_ctxt cx, ty::t t) -> result {
bcx.build.Store(umax(bcx, this_size, old_max_size), max_size); bcx.build.Store(umax(bcx, this_size, old_max_size), max_size);
} }
auto max_size_val = bcx.build.Load(max_size); auto max_size_val = bcx.build.Load(max_size);
auto total_size = if (std::ivec::len(variants) != 1u) { auto total_size = if (vec::len(variants) != 1u) {
bcx.build.Add(max_size_val, llsize_of(T_int())) bcx.build.Add(max_size_val, llsize_of(T_int()))
} else { max_size_val }; } else { max_size_val };
ret rslt(bcx, total_size); ret rslt(bcx, total_size);
@ -1524,7 +1516,7 @@ fn GEP_tup_like(&@block_ctxt cx, &ty::t t, ValueRef base, &vec[int] ixs) ->
// appropriate. @llblobptr is the data part of a tag value; its actual type is // appropriate. @llblobptr is the data part of a tag value; its actual type is
// meaningless, as it will be cast away. // meaningless, as it will be cast away.
fn GEP_tag(@block_ctxt cx, ValueRef llblobptr, &ast::def_id tag_id, fn GEP_tag(@block_ctxt cx, ValueRef llblobptr, &ast::def_id tag_id,
&ast::def_id variant_id, &ty::t[] ty_substs, int ix) -> result { &ast::def_id variant_id, &vec[ty::t] ty_substs, int ix) -> result {
auto variant = auto variant =
ty::tag_variant_with_id(cx.fcx.lcx.ccx.tcx, tag_id, variant_id); ty::tag_variant_with_id(cx.fcx.lcx.ccx.tcx, tag_id, variant_id);
// Synthesize a tuple type so that GEP_tup_like() can work its magic. // Synthesize a tuple type so that GEP_tup_like() can work its magic.
@ -2145,7 +2137,7 @@ fn make_drop_glue(&@block_ctxt cx, ValueRef v0, &ty::t t) {
} }
fn trans_res_drop(@block_ctxt cx, ValueRef rs, &ast::def_id did, fn trans_res_drop(@block_ctxt cx, ValueRef rs, &ast::def_id did,
ty::t inner_t, &ty::t[] tps) -> result { ty::t inner_t, &vec[ty::t] tps) -> result {
auto ccx = cx.fcx.lcx.ccx; auto ccx = cx.fcx.lcx.ccx;
auto inner_t_s = ty::substitute_type_params(ccx.tcx, tps, inner_t); auto inner_t_s = ty::substitute_type_params(ccx.tcx, tps, inner_t);
auto tup_ty = ty::mk_imm_tup(ccx.tcx, ~[ty::mk_int(ccx.tcx), inner_t_s]); auto tup_ty = ty::mk_imm_tup(ccx.tcx, ~[ty::mk_int(ccx.tcx), inner_t_s]);
@ -2653,9 +2645,9 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
} }
fn iter_variant(@block_ctxt cx, ValueRef a_tup, ValueRef b_tup, fn iter_variant(@block_ctxt cx, ValueRef a_tup, ValueRef b_tup,
&ty::variant_info variant, &ty::t[] tps, &ty::variant_info variant, &vec[ty::t] tps,
&ast::def_id tid, &val_pair_and_ty_fn f) -> result { &ast::def_id tid, &val_pair_and_ty_fn f) -> result {
if (std::ivec::len[ty::t](variant.args) == 0u) { if (vec::len[ty::t](variant.args) == 0u) {
ret rslt(cx, C_nil()); ret rslt(cx, C_nil());
} }
auto fn_ty = variant.ctor_ty; auto fn_ty = variant.ctor_ty;
@ -2664,10 +2656,12 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
case (ty::ty_fn(_, ?args, _, _, _)) { case (ty::ty_fn(_, ?args, _, _, _)) {
auto j = 0; auto j = 0;
for (ty::arg a in args) { for (ty::arg a in args) {
auto rslt = GEP_tag(cx, a_tup, tid, variant.id, tps, j); auto rslt = GEP_tag(cx, a_tup, tid,
variant.id, tps, j);
auto llfldp_a = rslt.val; auto llfldp_a = rslt.val;
cx = rslt.bcx; cx = rslt.bcx;
rslt = GEP_tag(cx, b_tup, tid, variant.id, tps, j); rslt = GEP_tag(cx, b_tup, tid,
variant.id, tps, j);
auto llfldp_b = rslt.val; auto llfldp_b = rslt.val;
cx = rslt.bcx; cx = rslt.bcx;
auto ty_subst = auto ty_subst =
@ -2713,12 +2707,8 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
} }
} }
case (ty::ty_res(_, ?inner, ?tps)) { case (ty::ty_res(_, ?inner, ?tps)) {
// FIXME: Remove this vec->ivec conversion.
auto tps_ivec = ~[];
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
auto inner1 = ty::substitute_type_params(cx.fcx.lcx.ccx.tcx, auto inner1 = ty::substitute_type_params(cx.fcx.lcx.ccx.tcx,
tps_ivec, inner); tps, inner);
r = GEP_tup_like(r.bcx, t, av, [0, 1]); r = GEP_tup_like(r.bcx, t, av, [0, 1]);
auto llfld_a = r.val; auto llfld_a = r.val;
r = GEP_tup_like(r.bcx, t, bv, [0, 1]); r = GEP_tup_like(r.bcx, t, bv, [0, 1]);
@ -2728,7 +2718,7 @@ fn iter_structural_ty_full(&@block_ctxt cx, ValueRef av, ValueRef bv,
} }
case (ty::ty_tag(?tid, ?tps)) { case (ty::ty_tag(?tid, ?tps)) {
auto variants = ty::tag_variants(cx.fcx.lcx.ccx.tcx, tid); auto variants = ty::tag_variants(cx.fcx.lcx.ccx.tcx, tid);
auto n_variants = std::ivec::len(variants); auto n_variants = vec::len(variants);
// Cast the tags to types we can GEP into. // Cast the tags to types we can GEP into.
if (n_variants == 1u) { if (n_variants == 1u) {
@ -4147,18 +4137,14 @@ fn autoderef_lval(&@block_ctxt cx, ValueRef v, &ty::t t, bool is_lval)
} else { v1 = body; } } else { v1 = body; }
} }
case (ty::ty_res(?did, ?inner, ?tps)) { case (ty::ty_res(?did, ?inner, ?tps)) {
// FIXME: Remove this vec->ivec conversion.
auto tps_ivec = ~[];
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
if (is_lval) { v1 = cx.build.Load(v1); } if (is_lval) { v1 = cx.build.Load(v1); }
t1 = ty::substitute_type_params(ccx.tcx, tps_ivec, inner); t1 = ty::substitute_type_params(ccx.tcx, tps, inner);
v1 = cx.build.GEP(v1, [C_int(0), C_int(1)]); v1 = cx.build.GEP(v1, [C_int(0), C_int(1)]);
} }
case (ty::ty_tag(?did, ?tps)) { case (ty::ty_tag(?did, ?tps)) {
auto variants = ty::tag_variants(ccx.tcx, did); auto variants = ty::tag_variants(ccx.tcx, did);
if (std::ivec::len(variants) != 1u || if (vec::len(variants) != 1u ||
std::ivec::len(variants.(0).args) != 1u) { vec::len(variants.(0).args) != 1u) {
break; break;
} }
if (is_lval) { v1 = cx.build.Load(v1); } if (is_lval) { v1 = cx.build.Load(v1); }
@ -4698,7 +4684,7 @@ fn trans_pat_match(&@block_ctxt cx, &@ast::pat pat, ValueRef llval,
auto matched_cx = new_sub_block_ctxt(cx, "matched_cx"); auto matched_cx = new_sub_block_ctxt(cx, "matched_cx");
auto llblobptr = llval; auto llblobptr = llval;
if (std::ivec::len(variants) == 1u) { if (vec::len(variants) == 1u) {
cx.build.Br(matched_cx.llbb); cx.build.Br(matched_cx.llbb);
} else { } else {
auto lltagptr = auto lltagptr =
@ -4726,19 +4712,14 @@ fn trans_pat_match(&@block_ctxt cx, &@ast::pat pat, ValueRef llval,
matched_cx.build.GEP(lltagptr, [C_int(0), C_int(1)]); matched_cx.build.GEP(lltagptr, [C_int(0), C_int(1)]);
} }
} }
auto ty_params = ty::node_id_to_type_params auto ty_params = ty::node_id_to_type_params
(cx.fcx.lcx.ccx.tcx, pat.id); (cx.fcx.lcx.ccx.tcx, pat.id);
// FIXME: Remove this vec->ivec conversion.
auto tps_ivec = ~[];
for (ty::t tp in ty_params) { tps_ivec += ~[tp]; }
if (vec::len(subpats) > 0u) { if (vec::len(subpats) > 0u) {
auto i = 0; auto i = 0;
for (@ast::pat subpat in subpats) { for (@ast::pat subpat in subpats) {
auto rslt = auto rslt =
GEP_tag(matched_cx, llblobptr, vdef._0, vdef._1, GEP_tag(matched_cx, llblobptr, vdef._0, vdef._1,
tps_ivec, i); ty_params, i);
auto llsubvalptr = rslt.val; auto llsubvalptr = rslt.val;
matched_cx = rslt.bcx; matched_cx = rslt.bcx;
auto llsubval = auto llsubval =
@ -4787,25 +4768,19 @@ fn trans_pat_binding(&@block_ctxt cx, &@ast::pat pat, ValueRef llval,
"trans_pat_binding: internal error, unbound var"); } "trans_pat_binding: internal error, unbound var"); }
} }
auto llblobptr = llval; auto llblobptr = llval;
if (std::ivec::len(ty::tag_variants(cx.fcx.lcx.ccx.tcx, vdef._0)) if (vec::len(ty::tag_variants(cx.fcx.lcx.ccx.tcx, vdef._0))!=1u) {
!= 1u) {
auto lltagptr = cx.build.PointerCast auto lltagptr = cx.build.PointerCast
(llval, T_opaque_tag_ptr(cx.fcx.lcx.ccx.tn)); (llval, T_opaque_tag_ptr(cx.fcx.lcx.ccx.tn));
llblobptr = cx.build.GEP(lltagptr, [C_int(0), C_int(1)]); llblobptr = cx.build.GEP(lltagptr, [C_int(0), C_int(1)]);
} }
auto ty_param_substs = auto ty_param_substs =
ty::node_id_to_type_params(cx.fcx.lcx.ccx.tcx, pat.id); ty::node_id_to_type_params(cx.fcx.lcx.ccx.tcx, pat.id);
// FIXME: Remove this vec->ivec conversion.
auto tps_ivec = ~[];
for (ty::t tp in ty_param_substs) { tps_ivec += ~[tp]; }
auto this_cx = cx; auto this_cx = cx;
auto i = 0; auto i = 0;
for (@ast::pat subpat in subpats) { for (@ast::pat subpat in subpats) {
auto rslt = auto rslt =
GEP_tag(this_cx, llblobptr, vdef._0, vdef._1, tps_ivec, GEP_tag(this_cx, llblobptr, vdef._0, vdef._1,
i); ty_param_substs, i);
this_cx = rslt.bcx; this_cx = rslt.bcx;
auto subpat_res = auto subpat_res =
trans_pat_binding(this_cx, subpat, rslt.val, true); trans_pat_binding(this_cx, subpat, rslt.val, true);
@ -4890,7 +4865,7 @@ fn lval_generic_fn(&@block_ctxt cx, &ty::ty_param_count_and_ty tpt,
lv = trans_external_path(cx, fn_id, tpt); lv = trans_external_path(cx, fn_id, tpt);
} }
auto tys = ty::node_id_to_type_params(cx.fcx.lcx.ccx.tcx, id); auto tys = ty::node_id_to_type_params(cx.fcx.lcx.ccx.tcx, id);
if (std::ivec::len[ty::t](tys) != 0u) { if (vec::len[ty::t](tys) != 0u) {
auto bcx = lv.res.bcx; auto bcx = lv.res.bcx;
let vec[ValueRef] tydescs = []; let vec[ValueRef] tydescs = [];
let vec[option::t[@tydesc_info]] tis = []; let vec[option::t[@tydesc_info]] tis = [];
@ -4986,8 +4961,7 @@ fn trans_path(&@block_ctxt cx, &ast::path p, ast::node_id id) -> lval_result {
auto bcx = alloc_result.bcx; auto bcx = alloc_result.bcx;
auto lltagptr = bcx.build.PointerCast auto lltagptr = bcx.build.PointerCast
(lltagblob, T_ptr(lltagty)); (lltagblob, T_ptr(lltagty));
if (std::ivec::len(ty::tag_variants(ccx.tcx, tid)) if (vec::len(ty::tag_variants(ccx.tcx, tid)) != 1u) {
!= 1u) {
auto lldiscrim_gv = auto lldiscrim_gv =
lookup_discriminant(bcx.fcx.lcx, tid, vid); lookup_discriminant(bcx.fcx.lcx, tid, vid);
auto lldiscrim = bcx.build.Load(lldiscrim_gv); auto lldiscrim = bcx.build.Load(lldiscrim_gv);
@ -8504,10 +8478,10 @@ fn trans_tag_variant(@local_ctxt cx, ast::node_id tag_id,
create_llargs_for_fn_args(fcx, ast::proto_fn, none[ty_self_pair], create_llargs_for_fn_args(fcx, ast::proto_fn, none[ty_self_pair],
ty::ret_ty_of_fn(cx.ccx.tcx, variant.node.id), ty::ret_ty_of_fn(cx.ccx.tcx, variant.node.id),
fn_args, ty_params); fn_args, ty_params);
let ty::t[] ty_param_substs = ~[]; let vec[ty::t] ty_param_substs = [];
i = 0u; i = 0u;
for (ast::ty_param tp in ty_params) { for (ast::ty_param tp in ty_params) {
ty_param_substs += ~[ty::mk_param(cx.ccx.tcx, i)]; ty_param_substs += [ty::mk_param(cx.ccx.tcx, i)];
i += 1u; i += 1u;
} }
auto arg_tys = arg_tys_of_fn(cx.ccx, variant.node.id); auto arg_tys = arg_tys_of_fn(cx.ccx, variant.node.id);

View file

@ -1,4 +1,5 @@
import std::vec;
import tritv::*; import tritv::*;
type precond = t; type precond = t;

View file

@ -24,36 +24,36 @@ import aux::crate_ctxt;
import aux::add_node; import aux::add_node;
import middle::tstate::ann::empty_ann; import middle::tstate::ann::empty_ann;
fn collect_ids_expr(&@expr e, @mutable node_id[] rs) { fn collect_ids_expr(&@expr e, @mutable vec[node_id] rs) {
*rs += ~[e.id]; vec::push(*rs, e.id);
} }
fn collect_ids_block(&block b, @mutable node_id[] rs) { fn collect_ids_block(&block b, @mutable vec[node_id] rs) {
*rs += ~[b.node.id]; vec::push(*rs, b.node.id);
} }
fn collect_ids_stmt(&@stmt s, @mutable node_id[] rs) { fn collect_ids_stmt(&@stmt s, @mutable vec[node_id] rs) {
alt (s.node) { alt (s.node) {
case (stmt_decl(_, ?id)) { case (stmt_decl(_, ?id)) {
log "node_id " + int::str(id); log "node_id " + int::str(id);
log_stmt(*s); log_stmt(*s);
*rs += ~[id]; vec::push(*rs, id);
} }
case (stmt_expr(_, ?id)) { case (stmt_expr(_, ?id)) {
log "node_id " + int::str(id); log "node_id " + int::str(id);
log_stmt(*s); log_stmt(*s);
*rs += ~[id]; vec::push(*rs, id);
} }
case (_) { } case (_) { }
} }
} }
fn collect_ids_local(&@local l, @mutable node_id[] rs) { fn collect_ids_local(&@local l, @mutable vec[node_id] rs) {
*rs += ~[l.node.id]; vec::push(*rs, l.node.id);
} }
fn node_ids_in_fn(&_fn f, &vec[ty_param] tps, &span sp, &fn_ident i, fn node_ids_in_fn(&_fn f, &vec[ty_param] tps, &span sp, &fn_ident i,
node_id id, @mutable node_id[] rs) { node_id id, @mutable vec[node_id] rs) {
auto collect_ids = walk::default_visitor(); auto collect_ids = walk::default_visitor();
collect_ids = collect_ids =
rec(visit_expr_pre=bind collect_ids_expr(_, rs), rec(visit_expr_pre=bind collect_ids_expr(_, rs),
@ -63,7 +63,7 @@ fn node_ids_in_fn(&_fn f, &vec[ty_param] tps, &span sp, &fn_ident i,
walk::walk_fn(collect_ids, f, tps, sp, i, id); walk::walk_fn(collect_ids, f, tps, sp, i, id);
} }
fn init_vecs(&crate_ctxt ccx, &node_id[] node_ids, uint len) { fn init_vecs(&crate_ctxt ccx, &vec[node_id] node_ids, uint len) {
for (node_id i in node_ids) { for (node_id i in node_ids) {
log int::str(i) + " |-> " + uint::str(len); log int::str(i) + " |-> " + uint::str(len);
add_node(ccx, i, empty_ann(len)); add_node(ccx, i, empty_ann(len));
@ -72,7 +72,7 @@ fn init_vecs(&crate_ctxt ccx, &node_id[] node_ids, uint len) {
fn visit_fn(&crate_ctxt ccx, uint num_constraints, &_fn f, &vec[ty_param] tps, fn visit_fn(&crate_ctxt ccx, uint num_constraints, &_fn f, &vec[ty_param] tps,
&span sp, &fn_ident i, node_id id) { &span sp, &fn_ident i, node_id id) {
let @mutable node_id[] node_ids = @mutable ~[]; let @mutable vec[node_id] node_ids = @mutable [];
node_ids_in_fn(f, tps, sp, i, id, node_ids); node_ids_in_fn(f, tps, sp, i, id, node_ids);
auto node_id_vec = *node_ids; auto node_id_vec = *node_ids;
init_vecs(ccx, node_id_vec, num_constraints); init_vecs(ccx, node_id_vec, num_constraints);

View file

@ -1,5 +1,8 @@
import std::ivec;
import std::str; import std::str;
import std::vec;
import std::vec::len;
import std::vec::grow;
import std::vec::pop;
import std::option; import std::option;
import std::option::none; import std::option::none;
import std::option::some; import std::option::some;
@ -45,7 +48,7 @@ fn def_id_to_str(def_id d) -> str {
ret int::str(d._0) + "," + int::str(d._1); ret int::str(d._0) + "," + int::str(d._1);
} }
fn comma_str(&(@constr_arg_use)[] args) -> str { fn comma_str(vec[@constr_arg_use] args) -> str {
auto rslt = ""; auto rslt = "";
auto comma = false; auto comma = false;
for (@constr_arg_use a in args) { for (@constr_arg_use a in args) {
@ -104,7 +107,7 @@ fn first_difference_string(&fn_ctxt fcx, &tritv::t expected, &tritv::t actual)
fn log_tritv_err(fn_ctxt fcx, tritv::t v) { log_err tritv_to_str(fcx, v); } fn log_tritv_err(fn_ctxt fcx, tritv::t v) { log_err tritv_to_str(fcx, v); }
fn tos(&uint[] v) -> str { fn tos(vec[uint] v) -> str {
auto rslt = ""; auto rslt = "";
for (uint i in v) { if (i == 0u) { rslt += "0"; } for (uint i in v) { if (i == 0u) { rslt += "0"; }
else if (i == 1u) { rslt += "1"; } else if (i == 1u) { rslt += "1"; }
@ -112,9 +115,9 @@ fn tos(&uint[] v) -> str {
ret rslt; ret rslt;
} }
fn log_cond(&uint[] v) { log tos(v); } fn log_cond(vec[uint] v) { log tos(v); }
fn log_cond_err(&uint[] v) { log_err tos(v); } fn log_cond_err(vec[uint] v) { log_err tos(v); }
fn log_pp(&pre_and_post pp) { fn log_pp(&pre_and_post pp) {
auto p1 = tritv::to_vec(pp.precondition); auto p1 = tritv::to_vec(pp.precondition);
@ -154,10 +157,10 @@ fn log_states_err(&pre_and_post_state pp) {
fn print_ident(&ident i) { log " " + i + " "; } fn print_ident(&ident i) { log " " + i + " "; }
fn print_idents(&mutable ident[] idents) { fn print_idents(vec[ident] idents) {
if (ivec::len[ident](idents) == 0u) { ret; } if (len[ident](idents) == 0u) {
log "an ident: " + ivec::pop[ident](idents); ret;
print_idents(idents); } else { log "an ident: " + pop[ident](idents); print_idents(idents); }
} }
@ -191,7 +194,7 @@ to represent predicate *arguments* however. This type
Both types store an ident and span, for error-logging purposes. Both types store an ident and span, for error-logging purposes.
*/ */
type pred_desc_ = rec((@constr_arg_use)[] args, uint bit_num); type pred_desc_ = rec(vec[@constr_arg_use] args, uint bit_num);
type pred_desc = spanned[pred_desc_]; type pred_desc = spanned[pred_desc_];
@ -199,13 +202,10 @@ type constr_arg_use = constr_arg_general[tup(ident, def_id)];
tag constraint { tag constraint {
cinit(uint, span, ident); cinit(uint, span, ident);
cpred(path, @mutable pred_desc[]); cpred(path, @mutable vec[pred_desc]);
} }
tag constr__ { tag constr__ { ninit(ident); npred(path, vec[@constr_arg_use]); }
ninit(ident);
npred(path, (@constr_arg_use)[]);
}
type constr_ = rec(node_id id, constr__ c); type constr_ = rec(node_id id, constr__ c);
@ -223,11 +223,11 @@ type fn_info = rec(constr_map constrs,
used*/ used*/
// Doesn't seem to work without the @ -- // Doesn't seem to work without the @ --
// bug? // bug?
@mutable node_id[] used_vars); @mutable vec[node_id] used_vars);
/* mapping from node ID to typestate annotation */ /* mapping from node ID to typestate annotation */
type node_ann_table = @mutable ts_ann[mutable]; type node_ann_table = @mutable vec[mutable ts_ann];
/* mapping from function name to fn_info map */ /* mapping from function name to fn_info map */
@ -243,15 +243,15 @@ fn get_fn_info(&crate_ctxt ccx, node_id id) -> fn_info {
} }
fn add_node(&crate_ctxt ccx, node_id i, &ts_ann a) { fn add_node(&crate_ctxt ccx, node_id i, &ts_ann a) {
auto sz = ivec::len(*ccx.node_anns); auto sz = len(*ccx.node_anns);
if (sz <= i as uint) { if (sz <= i as uint) {
ivec::grow_mut(*ccx.node_anns, (i as uint) - sz + 1u, empty_ann(0u)); grow(*ccx.node_anns, (i as uint) - sz + 1u, empty_ann(0u));
} }
ccx.node_anns.(i) = a; ccx.node_anns.(i) = a;
} }
fn get_ts_ann(&crate_ctxt ccx, node_id i) -> option::t[ts_ann] { fn get_ts_ann(&crate_ctxt ccx, node_id i) -> option::t[ts_ann] {
if (i as uint < ivec::len(*ccx.node_anns)) { if (i as uint < len(*ccx.node_anns)) {
ret some[ts_ann](ccx.node_anns.(i)); ret some[ts_ann](ccx.node_anns.(i));
} else { ret none[ts_ann]; } } else { ret none[ts_ann]; }
} }
@ -439,7 +439,7 @@ fn pure_exp(&crate_ctxt ccx, node_id id, &prestate p) -> bool {
fn num_constraints(fn_info m) -> uint { ret m.num_constraints; } fn num_constraints(fn_info m) -> uint { ret m.num_constraints; }
fn new_crate_ctxt(ty::ctxt cx) -> crate_ctxt { fn new_crate_ctxt(ty::ctxt cx) -> crate_ctxt {
let ts_ann[mutable] na = ~[mutable]; let vec[mutable ts_ann] na = vec::empty_mut();
ret rec(tcx=cx, node_anns=@mutable na, fm=@new_int_hash[fn_info]()); ret rec(tcx=cx, node_anns=@mutable na, fm=@new_int_hash[fn_info]());
} }
@ -453,10 +453,10 @@ fn controlflow_expr(&crate_ctxt ccx, @expr e) -> controlflow {
} }
} }
fn constraints_expr(&ty::ctxt cx, @expr e) -> (@ty::constr_def)[] { fn constraints_expr(&ty::ctxt cx, @expr e) -> vec[@ty::constr_def] {
alt (ty::struct(cx, ty::node_id_to_type(cx, e.id))) { alt (ty::struct(cx, ty::node_id_to_type(cx, e.id))) {
case (ty::ty_fn(_, _, _, _, ?cs)) { ret cs; } case (ty::ty_fn(_, _, _, _, ?cs)) { ret cs; }
case (_) { ret ~[]; } case (_) { ret []; }
} }
} }
@ -474,18 +474,19 @@ fn node_id_to_def(&crate_ctxt ccx, node_id id) -> option::t[def] {
ret ccx.tcx.def_map.find(id); ret ccx.tcx.def_map.find(id);
} }
fn norm_a_constraint(node_id id, &constraint c) -> norm_constraint[] { fn norm_a_constraint(node_id id, &constraint c) -> vec[norm_constraint] {
alt (c) { alt (c) {
case (cinit(?n, ?sp, ?i)) { case (cinit(?n, ?sp, ?i)) {
ret ~[rec(bit_num=n, c=respan(sp, rec(id=id, c=ninit(i))))]; ret [rec(bit_num=n, c=respan(sp, rec(id=id, c=ninit(i))))];
} }
case (cpred(?p, ?descs)) { case (cpred(?p, ?descs)) {
let norm_constraint[] rslt = ~[]; let vec[norm_constraint] rslt = [];
for (pred_desc pd in *descs) { for (pred_desc pd in *descs) {
rslt += ~[rec(bit_num=pd.node.bit_num, vec::push(rslt,
rec(bit_num=pd.node.bit_num,
c=respan(pd.span, c=respan(pd.span,
rec(id=id, rec(id=id,
c=npred(p, pd.node.args))))]; c=npred(p, pd.node.args)))));
} }
ret rslt; ret rslt;
} }
@ -495,15 +496,15 @@ fn norm_a_constraint(node_id id, &constraint c) -> norm_constraint[] {
// Tried to write this as an iterator, but I got a // Tried to write this as an iterator, but I got a
// non-exhaustive match in trans. // non-exhaustive match in trans.
fn constraints(&fn_ctxt fcx) -> norm_constraint[] { fn constraints(&fn_ctxt fcx) -> vec[norm_constraint] {
let norm_constraint[] rslt = ~[]; let vec[norm_constraint] rslt = [];
for each (@tup(node_id, constraint) p in fcx.enclosing.constrs.items()) { for each (@tup(node_id, constraint) p in fcx.enclosing.constrs.items()) {
rslt += norm_a_constraint(p._0, p._1); rslt += norm_a_constraint(p._0, p._1);
} }
ret rslt; ret rslt;
} }
fn match_args(&fn_ctxt fcx, &pred_desc[] occs, &(@constr_arg_use)[] occ) -> fn match_args(&fn_ctxt fcx, vec[pred_desc] occs, vec[@constr_arg_use] occ) ->
uint { uint {
log "match_args: looking at " + log "match_args: looking at " +
constr_args_to_str(std::util::fst[ident, def_id], occ); constr_args_to_str(std::util::fst[ident, def_id], occ);
@ -512,13 +513,7 @@ fn match_args(&fn_ctxt fcx, &pred_desc[] occs, &(@constr_arg_use)[] occ) ->
fn eq(&tup(ident, def_id) p, &tup(ident, def_id) q) -> bool { fn eq(&tup(ident, def_id) p, &tup(ident, def_id) q) -> bool {
ret p._1 == q._1; ret p._1 == q._1;
} }
if (ty::args_eq(eq, pd.node.args, occ)) { ret pd.node.bit_num; }
// FIXME: Remove this vec->ivec conversion.
let (@constr_arg_use)[] cau_ivec = ~[];
for (@constr_arg_use cau in pd.node.args) {
cau_ivec += ~[cau];
}
if (ty::args_eq(eq, cau_ivec, occ)) { ret pd.node.bit_num; }
} }
fcx.ccx.tcx.sess.bug("match_args: no match for occurring args"); fcx.ccx.tcx.sess.bug("match_args: no match for occurring args");
} }
@ -563,10 +558,10 @@ fn expr_to_constr_arg(ty::ctxt tcx, &@expr e) -> @constr_arg_use {
} }
} }
fn exprs_to_constr_args(ty::ctxt tcx, &(@expr)[] args) fn exprs_to_constr_args(ty::ctxt tcx, vec[@expr] args) ->
-> (@constr_arg_use)[] { vec[@constr_arg_use] {
auto f = bind expr_to_constr_arg(tcx, _); auto f = bind expr_to_constr_arg(tcx, _);
ret ivec::map(f, args); ret vec::map(f, args);
} }
fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr { fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr {
@ -577,14 +572,10 @@ fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr {
expr_call(?operator, ?args)) { expr_call(?operator, ?args)) {
alt (operator.node) { alt (operator.node) {
case (expr_path(?p)) { case (expr_path(?p)) {
// FIXME: Remove this vec->ivec conversion.
auto args_ivec = ~[];
for (@expr e in args) { args_ivec += ~[e]; }
ret respan(e.span, ret respan(e.span,
rec(id=node_id_for_constr(tcx, operator.id), rec(id=node_id_for_constr(tcx, operator.id),
c=npred(p, exprs_to_constr_args(tcx, c=npred(p,
args_ivec)))); exprs_to_constr_args(tcx, args))));
} }
case (_) { case (_) {
tcx.sess.span_fatal(operator.span, tcx.sess.span_fatal(operator.span,
@ -602,30 +593,24 @@ fn expr_to_constr(ty::ctxt tcx, &@expr e) -> constr {
} }
fn pred_desc_to_str(&pred_desc p) -> str { fn pred_desc_to_str(&pred_desc p) -> str {
// FIXME: Remove this vec->ivec conversion.
let (@constr_arg_use)[] cau_ivec = ~[];
for (@constr_arg_use cau in p.node.args) {
cau_ivec += ~[cau];
}
ret "<" + uint::str(p.node.bit_num) + ", " + ret "<" + uint::str(p.node.bit_num) + ", " +
constr_args_to_str(std::util::fst[ident, def_id], cau_ivec) + ">"; constr_args_to_str(std::util::fst[ident, def_id], p.node.args) + ">";
} }
fn substitute_constr_args(&ty::ctxt cx, &(@expr)[] actuals, fn substitute_constr_args(&ty::ctxt cx, &vec[@expr] actuals,
&@ty::constr_def c) -> constr__ { &@ty::constr_def c) -> constr__ {
let (@constr_arg_use)[] rslt = ~[]; let vec[@constr_arg_use] rslt = [];
for (@constr_arg a in c.node.args) { for (@constr_arg a in c.node.args) {
rslt += ~[substitute_arg(cx, actuals, a)]; rslt += [substitute_arg(cx, actuals, a)];
} }
ret npred(c.node.path, rslt); ret npred(c.node.path, rslt);
} }
type subst = tup(arg, @expr)[]; type subst = vec[tup(arg, @expr)];
fn substitute_arg(&ty::ctxt cx, &(@expr)[] actuals, @constr_arg a) -> fn substitute_arg(&ty::ctxt cx, &vec[@expr] actuals, @constr_arg a) ->
@constr_arg_use { @constr_arg_use {
auto num_actuals = ivec::len(actuals); auto num_actuals = vec::len(actuals);
alt (a.node) { alt (a.node) {
case (carg_ident(?i)) { case (carg_ident(?i)) {
if (i < num_actuals) { if (i < num_actuals) {
@ -641,7 +626,7 @@ fn substitute_arg(&ty::ctxt cx, &(@expr)[] actuals, @constr_arg a) ->
} }
fn path_to_ident(&ty::ctxt cx, &path p) -> ident { fn path_to_ident(&ty::ctxt cx, &path p) -> ident {
alt (ivec::last(p.node.idents)) { alt (vec::last(p.node.idents)) {
case (none) { cx.sess.span_fatal(p.span, "Malformed path"); } case (none) { cx.sess.span_fatal(p.span, "Malformed path"); }
case (some(?i)) { ret i; } case (some(?i)) { ret i; }
} }
@ -781,28 +766,26 @@ fn non_init_constraint_mentions(&fn_ctxt fcx, &norm_constraint c,
} }
fn args_mention(&(@constr_arg_use)[] args, &def_id v) -> bool { fn args_mention(&vec[@constr_arg_use] args, &def_id v) -> bool {
fn mentions(&def_id v, &@constr_arg_use a) -> bool { fn mentions(&def_id v, &@constr_arg_use a) -> bool {
alt (a.node) { alt (a.node) {
case (carg_ident(?p1)) { p1._1 == v } case (carg_ident(?p1)) { p1._1 == v }
case (_) { false } case (_) { false }
} }
} }
ret ivec::any[@constr_arg_use](bind mentions(v,_), args); ret util::common::any[@constr_arg_use](bind mentions(v,_), args);
} }
fn use_var(&fn_ctxt fcx, &node_id v) { fn use_var(&fn_ctxt fcx, &node_id v) {
*fcx.enclosing.used_vars += ~[v]; vec::push(*fcx.enclosing.used_vars, v);
} }
// FIXME: This should be a function in std::ivec::. fn vec_contains(&@mutable vec[node_id] v, &node_id i) -> bool {
fn vec_contains(&@mutable (node_id[]) v, &node_id i) -> bool {
for (node_id d in *v) { for (node_id d in *v) {
if (d == i) { ret true; } if (d == i) { ret true; }
} }
ret false; ret false;
} }
// //
// Local Variables: // Local Variables:
// mode: rust // mode: rust

View file

@ -1,9 +1,10 @@
import syntax::ast::*; import syntax::ast::*;
import syntax::walk; import syntax::walk;
import std::ivec;
import std::option::*; import std::option::*;
import aux::constr_arg_use; import std::vec;
import std::vec::len;
import std::vec::slice;
import aux::local_node_id_to_def; import aux::local_node_id_to_def;
import aux::fn_ctxt; import aux::fn_ctxt;
import aux::fn_info; import aux::fn_info;
@ -62,15 +63,7 @@ fn bit_num(&fn_ctxt fcx, &constr_ c) -> uint {
} }
case (npred(_, ?args)) { case (npred(_, ?args)) {
alt (rslt) { alt (rslt) {
case (cpred(_, ?descs)) { case (cpred(_, ?descs)) { ret match_args(fcx, *descs, args); }
// FIXME: Remove this vec->ivec conversion.
let (@constr_arg_use)[] cau_ivec = ~[];
for (@constr_arg_use cau in args) {
cau_ivec += ~[cau];
}
auto d = *descs;
ret match_args(fcx, d, cau_ivec);
}
case (_) { case (_) {
fcx.ccx.tcx.sess.bug("bit_num: asked for pred constraint," fcx.ccx.tcx.sess.bug("bit_num: asked for pred constraint,"
+ " found an init constraint"); + " found an init constraint");
@ -105,11 +98,11 @@ fn seq_tritv(&postcond p, &postcond q) {
} }
} }
fn seq_postconds(&fn_ctxt fcx, &postcond[] ps) -> postcond { fn seq_postconds(&fn_ctxt fcx, &vec[postcond] ps) -> postcond {
auto sz = ivec::len(ps); auto sz = vec::len(ps);
if (sz >= 1u) { if (sz >= 1u) {
auto prev = tritv_clone(ps.(0)); auto prev = tritv_clone(ps.(0));
for (postcond p in ivec::slice(ps, 1u, sz)) { for (postcond p in slice(ps, 1u, sz)) {
seq_tritv(prev, p); seq_tritv(prev, p);
} }
ret prev; ret prev;
@ -123,14 +116,14 @@ fn seq_postconds(&fn_ctxt fcx, &postcond[] ps) -> postcond {
// return the precondition for evaluating each expr in order. // return the precondition for evaluating each expr in order.
// So, if e0's post is {x} and e1's pre is {x, y, z}, the entire // So, if e0's post is {x} and e1's pre is {x, y, z}, the entire
// precondition shouldn't include x. // precondition shouldn't include x.
fn seq_preconds(&fn_ctxt fcx, &pre_and_post[] pps) -> precond { fn seq_preconds(&fn_ctxt fcx, &vec[pre_and_post] pps) -> precond {
let uint sz = ivec::len(pps); let uint sz = len(pps);
let uint num_vars = num_constraints(fcx.enclosing); let uint num_vars = num_constraints(fcx.enclosing);
fn seq_preconds_go(&fn_ctxt fcx, &pre_and_post[] pps, fn seq_preconds_go(&fn_ctxt fcx, &vec[pre_and_post] pps,
&pre_and_post first) &pre_and_post first)
-> precond { -> precond {
let uint sz = ivec::len(pps); let uint sz = len(pps);
if (sz >= 1u) { if (sz >= 1u) {
auto second = pps.(0); auto second = pps.(0);
assert (pps_len(second) == num_constraints(fcx.enclosing)); assert (pps_len(second) == num_constraints(fcx.enclosing));
@ -140,7 +133,7 @@ fn seq_preconds(&fn_ctxt fcx, &pre_and_post[] pps) -> precond {
union(next_first, second_pre); union(next_first, second_pre);
auto next_first_post = clone(first.postcondition); auto next_first_post = clone(first.postcondition);
seq_tritv(next_first_post, second.postcondition); seq_tritv(next_first_post, second.postcondition);
ret seq_preconds_go(fcx, ivec::slice(pps, 1u, sz), ret seq_preconds_go(fcx, slice(pps, 1u, sz),
@rec(precondition=next_first, @rec(precondition=next_first,
postcondition=next_first_post)); postcondition=next_first_post));
} }
@ -152,7 +145,7 @@ fn seq_preconds(&fn_ctxt fcx, &pre_and_post[] pps) -> precond {
if (sz >= 1u) { if (sz >= 1u) {
auto first = pps.(0); auto first = pps.(0);
assert (pps_len(first) == num_vars); assert (pps_len(first) == num_vars);
ret seq_preconds_go(fcx, ivec::slice(pps, 1u, sz), first); ret seq_preconds_go(fcx, slice(pps, 1u, sz), first);
} else { ret true_precond(num_vars); } } else { ret true_precond(num_vars); }
} }
@ -230,7 +223,7 @@ fn kill_poststate(&fn_ctxt fcx, node_id id, &constr_ c) -> bool {
fn clear_in_poststate_expr(&fn_ctxt fcx, &@expr e, &poststate t) { fn clear_in_poststate_expr(&fn_ctxt fcx, &@expr e, &poststate t) {
alt (e.node) { alt (e.node) {
case (expr_path(?p)) { case (expr_path(?p)) {
alt (ivec::last(p.node.idents)) { alt (vec::last(p.node.idents)) {
case (some(?i)) { case (some(?i)) {
alt (local_node_id_to_def(fcx, e.id)) { alt (local_node_id_to_def(fcx, e.id)) {
case (some(def_local(?d_id))) { case (some(def_local(?d_id))) {

View file

@ -33,6 +33,12 @@ import tstate::ann::prestate;
import tstate::ann::implies; import tstate::ann::implies;
import tstate::ann::ann_precond; import tstate::ann::ann_precond;
import tstate::ann::ann_prestate; import tstate::ann::ann_prestate;
import std::vec::map;
import std::vec;
import std::vec::slice;
import std::vec::unzip;
import std::vec::plus_option;
import std::vec::cat_options;
import std::option; import std::option;
import std::option::t; import std::option::t;
import std::option::some; import std::option::some;

View file

@ -1,6 +1,6 @@
import std::ivec;
import std::vec; import std::vec;
import std::vec::plus_option;
import syntax::ast::*; import syntax::ast::*;
import util::ppaux::fn_ident_to_string; import util::ppaux::fn_ident_to_string;
import std::option::*; import std::option::*;
@ -26,36 +26,32 @@ import util::common::new_def_hash;
import syntax::codemap::span; import syntax::codemap::span;
import syntax::ast::respan; import syntax::ast::respan;
type ctxt = rec(@mutable (aux::constr[]) cs, ty::ctxt tcx); type ctxt = rec(@mutable vec[aux::constr] cs, ty::ctxt tcx);
fn collect_local(&@local loc, &ctxt cx, &visit::vt[ctxt] v) { fn collect_local(&@local loc, &ctxt cx, &visit::vt[ctxt] v) {
log "collect_local: pushing " + loc.node.ident; log "collect_local: pushing " + loc.node.ident;
*cx.cs += ~[respan(loc.span, rec(id=loc.node.id, vec::push(*cx.cs,
c=ninit(loc.node.ident)))]; respan(loc.span, rec(id=loc.node.id, c=ninit(loc.node.ident))));
visit::visit_local(loc, cx, v); visit::visit_local(loc, cx, v);
} }
fn collect_pred(&@expr e, &ctxt cx, &visit::vt[ctxt] v) { fn collect_pred(&@expr e, &ctxt cx, &visit::vt[ctxt] v) {
alt (e.node) { alt (e.node) {
case (expr_check(_, ?ch)) { case (expr_check(_, ?ch)) {
*cx.cs += ~[expr_to_constr(cx.tcx, ch)]; vec::push(*cx.cs, expr_to_constr(cx.tcx, ch));
} }
case (expr_if_check(?ex, _, _)) { case (expr_if_check(?ex, _, _)) {
*cx.cs += ~[expr_to_constr(cx.tcx, ex)]; vec::push(*cx.cs, expr_to_constr(cx.tcx, ex));
} }
// If it's a call, generate appropriate instances of the // If it's a call, generate appropriate instances of the
// call's constraints. // call's constraints.
case (expr_call(?operator, ?operands)) { case (expr_call(?operator, ?operands)) {
// FIXME: Remove this vec->ivec conversion.
auto operands_ivec = ~[];
for (@expr opd in operands) { operands_ivec += ~[opd]; }
for (@ty::constr_def c in constraints_expr(cx.tcx, operator)) { for (@ty::constr_def c in constraints_expr(cx.tcx, operator)) {
let aux::constr ct = respan(c.span, let aux::constr ct = respan(c.span,
rec(id=c.node.id._1, rec(id=c.node.id._1,
c=aux::substitute_constr_args(cx.tcx, c=aux::substitute_constr_args(cx.tcx,
operands_ivec, c))); operands, c)));
*cx.cs += ~[ct]; vec::push(*cx.cs, ct);
} }
} }
case (_) { } case (_) { }
@ -71,7 +67,7 @@ fn do_nothing(&_fn f, &vec[ty_param] tp, &span sp, &fn_ident i,
fn find_locals(&ty::ctxt tcx, &_fn f, &vec[ty_param] tps, fn find_locals(&ty::ctxt tcx, &_fn f, &vec[ty_param] tps,
&span sp, &fn_ident i, node_id id) &span sp, &fn_ident i, node_id id)
-> ctxt { -> ctxt {
let ctxt cx = rec(cs=@mutable ~[], tcx=tcx); let ctxt cx = rec(cs=@mutable vec::alloc(0u), tcx=tcx);
auto visitor = visit::default_visitor[ctxt](); auto visitor = visit::default_visitor[ctxt]();
visitor = visitor =
@ -97,17 +93,18 @@ fn add_constraint(&ty::ctxt tcx, aux::constr c, uint next, constr_map tbl) ->
" as a variable and a pred"); " as a variable and a pred");
} }
case (cpred(_, ?pds)) { case (cpred(_, ?pds)) {
*pds += ~[respan(c.span, vec::push(*pds,
rec(args=args, bit_num=next))]; respan(c.span,
rec(args=args, bit_num=next)));
} }
} }
} }
case (none) { case (none) {
tbl.insert(c.node.id, tbl.insert(c.node.id,
cpred(p, cpred(p,
@mutable ~[respan(c.span, @mutable [respan(c.span,
rec(args=args, rec(args=args,
bit_num=next))])); bit_num=next))]));
} }
} }
} }
@ -137,10 +134,10 @@ fn mk_fn_info(&crate_ctxt ccx, &_fn f, &vec[ty_param] tp,
auto name = fn_ident_to_string(id, f_name); auto name = fn_ident_to_string(id, f_name);
add_constraint(cx.tcx, respan(f_sp, rec(id=id, c=ninit(name))), next, add_constraint(cx.tcx, respan(f_sp, rec(id=id, c=ninit(name))), next,
res_map); res_map);
let @mutable node_id[] v = @mutable ~[]; let @mutable vec[node_id] v = @mutable [];
auto rslt = auto rslt =
rec(constrs=res_map, rec(constrs=res_map,
num_constraints=ivec::len(*cx.cs) + 1u, num_constraints=vec::len(*cx.cs) + 1u,
cf=f.decl.cf, cf=f.decl.cf,
used_vars=v); used_vars=v);
ccx.fm.insert(id, rslt); ccx.fm.insert(id, rslt);

View file

@ -1,5 +1,4 @@
import std::ivec;
import std::vec; import std::vec;
import std::vec::plus_option; import std::vec::plus_option;
import std::option; import std::option;
@ -111,7 +110,7 @@ fn find_pre_post_item(&crate_ctxt ccx, &item i) {
alt (i.node) { alt (i.node) {
case (item_const(_, ?e)) { case (item_const(_, ?e)) {
// make a fake fcx // make a fake fcx
let @mutable node_id[] v = @mutable ~[]; let @mutable vec[node_id] v = @mutable [];
auto fake_fcx = auto fake_fcx =
rec(enclosing=rec(constrs=@new_int_hash[constraint](), rec(enclosing=rec(constrs=@new_int_hash[constraint](),
num_constraints=0u, num_constraints=0u,
@ -164,13 +163,9 @@ fn find_pre_post_exprs(&fn_ctxt fcx, &vec[@expr] args, node_id id) {
} }
auto g = bind get_pp(fcx.ccx, _); auto g = bind get_pp(fcx.ccx, _);
auto pps = vec::map[@expr, pre_and_post](g, args); auto pps = vec::map[@expr, pre_and_post](g, args);
auto h = get_post;
// TODO: Remove this vec->ivec conversion. set_pre_and_post(fcx.ccx, id, seq_preconds(fcx, pps),
auto pps_ivec = ~[]; seq_postconds(fcx, vec::map(h, pps)));
for (pre_and_post pp in pps) { pps_ivec += ~[pp]; }
set_pre_and_post(fcx.ccx, id, seq_preconds(fcx, pps_ivec),
seq_postconds(fcx, ivec::map(get_post, pps_ivec)));
} }
fn find_pre_post_loop(&fn_ctxt fcx, &@local l, &@expr index, &block body, fn find_pre_post_loop(&fn_ctxt fcx, &@local l, &@expr index, &block body,
@ -184,8 +179,10 @@ fn find_pre_post_loop(&fn_ctxt fcx, &@local l, &@expr index, &block body,
// so we pretend they're used // so we pretend they're used
use_var(fcx, l.node.id); use_var(fcx, l.node.id);
auto loop_precond = seq_preconds(fcx, ~[expr_pp(fcx.ccx, index), auto loop_precond =
block_pp(fcx.ccx, body)]); seq_preconds(fcx,
[expr_pp(fcx.ccx, index),
block_pp(fcx.ccx, body)]);
auto loop_postcond = intersect_states(expr_postcond(fcx.ccx, index), auto loop_postcond = intersect_states(expr_postcond(fcx.ccx, index),
block_postcond(fcx.ccx, body)); block_postcond(fcx.ccx, body));
copy_pre_post_(fcx.ccx, id, loop_precond, loop_postcond); copy_pre_post_(fcx.ccx, id, loop_precond, loop_postcond);
@ -208,8 +205,10 @@ fn join_then_else(&fn_ctxt fcx, &@expr antec, &block conseq,
case (_) {} case (_) {}
} }
auto precond_res = seq_preconds(fcx, auto precond_res =
~[expr_pp(fcx.ccx, antec), block_pp(fcx.ccx, conseq)]); seq_preconds(fcx,
[expr_pp(fcx.ccx, antec),
block_pp(fcx.ccx, conseq)]);
set_pre_and_post(fcx.ccx, id, precond_res, set_pre_and_post(fcx.ccx, id, precond_res,
expr_poststate(fcx.ccx, antec)); expr_poststate(fcx.ccx, antec));
} }
@ -220,11 +219,13 @@ fn join_then_else(&fn_ctxt fcx, &@expr antec, &block conseq,
is *not* true in the alternative is *not* true in the alternative
*/ */
find_pre_post_expr(fcx, altern); find_pre_post_expr(fcx, altern);
auto precond_false_case = seq_preconds(fcx, auto precond_false_case =
~[expr_pp(fcx.ccx, antec), expr_pp(fcx.ccx, altern)]); seq_preconds(fcx,
auto postcond_false_case = seq_postconds(fcx, [expr_pp(fcx.ccx, antec),
~[expr_postcond(fcx.ccx, antec), expr_pp(fcx.ccx, altern)]);
expr_postcond(fcx.ccx, altern)]); auto postcond_false_case =
seq_postconds(fcx, [expr_postcond(fcx.ccx, antec),
expr_postcond(fcx.ccx, altern)]);
/* Be sure to set the bit for the check condition here, /* Be sure to set the bit for the check condition here,
so that it's *not* set in the alternative. */ so that it's *not* set in the alternative. */
@ -235,14 +236,17 @@ fn join_then_else(&fn_ctxt fcx, &@expr antec, &block conseq,
} }
case (_) {} case (_) {}
} }
auto precond_true_case = seq_preconds(fcx, auto precond_true_case =
~[expr_pp(fcx.ccx, antec), block_pp(fcx.ccx, conseq)]); seq_preconds(fcx,
auto postcond_true_case = seq_postconds(fcx, [expr_pp(fcx.ccx, antec),
~[expr_postcond(fcx.ccx, antec), block_pp(fcx.ccx, conseq)]);
block_postcond(fcx.ccx, conseq)]); auto postcond_true_case =
seq_postconds(fcx, [expr_postcond(fcx.ccx, antec),
block_postcond(fcx.ccx, conseq)]);
auto precond_res = seq_postconds(fcx, ~[precond_true_case, auto precond_res =
precond_false_case]); seq_postconds(fcx, [precond_true_case,
precond_false_case]);
auto postcond_res = auto postcond_res =
intersect_states(postcond_true_case, postcond_false_case); intersect_states(postcond_true_case, postcond_false_case);
set_pre_and_post(fcx.ccx, id, precond_res, postcond_res); set_pre_and_post(fcx.ccx, id, precond_res, postcond_res);
@ -282,11 +286,6 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
case (expr_call(?operator, ?operands)) { case (expr_call(?operator, ?operands)) {
auto args = vec::clone(operands); auto args = vec::clone(operands);
vec::push(args, operator); vec::push(args, operator);
// TODO: Remove this vec->ivec conversion.
auto operands_ivec = ~[];
for (@expr e in operands) { operands_ivec += ~[e]; }
find_pre_post_exprs(fcx, args, e.id); find_pre_post_exprs(fcx, args, e.id);
/* see if the call has any constraints on its type */ /* see if the call has any constraints on its type */
for (@ty::constr_def c in constraints_expr(fcx.ccx.tcx, operator)) for (@ty::constr_def c in constraints_expr(fcx.ccx.tcx, operator))
@ -295,8 +294,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
bit_num(fcx, bit_num(fcx,
rec(id=c.node.id._1, rec(id=c.node.id._1,
c=substitute_constr_args(fcx.ccx.tcx, c=substitute_constr_args(fcx.ccx.tcx,
operands_ivec, operands, c)));
c)));
require(i, expr_pp(fcx.ccx, e)); require(i, expr_pp(fcx.ccx, e));
} }
@ -442,7 +440,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
find_pre_post_expr(fcx, l); find_pre_post_expr(fcx, l);
find_pre_post_expr(fcx, r); find_pre_post_expr(fcx, r);
auto overall_pre = seq_preconds(fcx, auto overall_pre = seq_preconds(fcx,
~[expr_pp(fcx.ccx, l), expr_pp(fcx.ccx, r)]); [expr_pp(fcx.ccx, l), expr_pp(fcx.ccx, r)]);
set_precondition(node_id_to_ts_ann(fcx.ccx, e.id), set_precondition(node_id_to_ts_ann(fcx.ccx, e.id),
overall_pre); overall_pre);
set_postcondition(node_id_to_ts_ann(fcx.ccx, e.id), set_postcondition(node_id_to_ts_ann(fcx.ccx, e.id),
@ -467,18 +465,20 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
find_pre_post_expr(fcx, test); find_pre_post_expr(fcx, test);
find_pre_post_block(fcx, body); find_pre_post_block(fcx, body);
set_pre_and_post(fcx.ccx, e.id, set_pre_and_post(fcx.ccx, e.id,
seq_preconds(fcx, ~[expr_pp(fcx.ccx, test), seq_preconds(fcx,
block_pp(fcx.ccx, body)]), [expr_pp(fcx.ccx, test),
block_pp(fcx.ccx, body)]),
intersect_states(expr_postcond(fcx.ccx, test), intersect_states(expr_postcond(fcx.ccx, test),
block_postcond(fcx.ccx, body))); block_postcond(fcx.ccx,
body)));
} }
case (expr_do_while(?body, ?test)) { case (expr_do_while(?body, ?test)) {
find_pre_post_block(fcx, body); find_pre_post_block(fcx, body);
find_pre_post_expr(fcx, test); find_pre_post_expr(fcx, test);
auto loop_postcond = seq_postconds(fcx, auto loop_postcond =
~[block_postcond(fcx.ccx, body), seq_postconds(fcx, [block_postcond(fcx.ccx, body),
expr_postcond(fcx.ccx, test)]); expr_postcond(fcx.ccx, test)]);
/* conservative approximation: if the body /* conservative approximination: if the body
could break or cont, the test may never be executed */ could break or cont, the test may never be executed */
if (has_nonlocal_exits(body)) { if (has_nonlocal_exits(body)) {
@ -486,8 +486,8 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
} }
set_pre_and_post(fcx.ccx, e.id, set_pre_and_post(fcx.ccx, e.id,
seq_preconds(fcx, seq_preconds(fcx,
~[block_pp(fcx.ccx, body), [block_pp(fcx.ccx, body),
expr_pp(fcx.ccx, test)]), expr_pp(fcx.ccx, test)]),
loop_postcond); loop_postcond);
} }
case (expr_for(?d, ?index, ?body)) { case (expr_for(?d, ?index, ?body)) {
@ -509,7 +509,7 @@ fn find_pre_post_expr(&fn_ctxt fcx, @expr e) {
auto alt_pps = vec::map[arm, pre_and_post](f, alts); auto alt_pps = vec::map[arm, pre_and_post](f, alts);
fn combine_pp(pre_and_post antec, fn_ctxt fcx, &pre_and_post pp, fn combine_pp(pre_and_post antec, fn_ctxt fcx, &pre_and_post pp,
&pre_and_post next) -> pre_and_post { &pre_and_post next) -> pre_and_post {
union(pp.precondition, seq_preconds(fcx, ~[antec, next])); union(pp.precondition, seq_preconds(fcx, [antec, next]));
intersect(pp.postcondition, next.postcondition); intersect(pp.postcondition, next.postcondition);
ret pp; ret pp;
} }
@ -664,23 +664,27 @@ fn find_pre_post_block(&fn_ctxt fcx, block b) {
fn do_inner_(fn_ctxt fcx, &@expr e) { find_pre_post_expr(fcx, e); } fn do_inner_(fn_ctxt fcx, &@expr e) { find_pre_post_expr(fcx, e); }
auto do_inner = bind do_inner_(fcx, _); auto do_inner = bind do_inner_(fcx, _);
option::map[@expr, ()](do_inner, b.node.expr); option::map[@expr, ()](do_inner, b.node.expr);
let vec[pre_and_post] pps = [];
let pre_and_post[] pps = ~[]; fn get_pp_stmt(crate_ctxt ccx, &@stmt s) -> pre_and_post {
for (@stmt s in b.node.stmts) { pps += ~[stmt_pp(fcx.ccx, *s)]; } ret stmt_pp(ccx, *s);
alt (b.node.expr) {
case (none) { /* no-op */ }
case (some(?e)) { pps += ~[expr_pp(fcx.ccx, e)]; }
} }
auto f = bind get_pp_stmt(fcx.ccx, _);
pps += vec::map[@stmt, pre_and_post](f, b.node.stmts);
fn get_pp_expr(crate_ctxt ccx, &@expr e) -> pre_and_post {
ret expr_pp(ccx, e);
}
auto g = bind get_pp_expr(fcx.ccx, _);
plus_option[pre_and_post](pps,
option::map[@expr,
pre_and_post](g, b.node.expr));
auto block_precond = seq_preconds(fcx, pps); auto block_precond = seq_preconds(fcx, pps);
auto h = get_post;
auto postconds = ~[]; auto postconds = vec::map[pre_and_post, postcond](h, pps);
for (pre_and_post pp in pps) { postconds += ~[get_post(pp)]; }
/* A block may be empty, so this next line ensures that the postconds /* A block may be empty, so this next line ensures that the postconds
vector is non-empty. */ vector is non-empty. */
postconds += ~[block_precond];
vec::push[postcond](postconds, block_precond);
auto block_postcond = empty_poststate(nv); auto block_postcond = empty_poststate(nv);
/* conservative approximation */ /* conservative approximation */

View file

@ -240,11 +240,11 @@ fn tritv_doesntcare(&t v) -> bool {
ret true; ret true;
} }
fn to_vec(&t v) -> uint[] { fn to_vec(&t v) -> vec[uint] {
let uint i = 0u; let uint i = 0u;
let uint[] rslt = ~[]; let vec[uint] rslt = [];
while (i < v.nbits) { while (i < v.nbits) {
rslt += ~[alt (tritv_get(v, i)) { rslt += [alt (tritv_get(v, i)) {
case (dont_care) { 2u } case (dont_care) { 2u }
case (ttrue) { 1u } case (ttrue) { 1u }
case (tfalse) { 0u } }]; case (tfalse) { 0u } }];

View file

@ -196,9 +196,9 @@ type method =
arg[] inputs, arg[] inputs,
t output, t output,
controlflow cf, controlflow cf,
(@constr_def)[] constrs); vec[@constr_def] constrs);
type constr_table = hashmap[ast::node_id, constr_def[]]; type constr_table = hashmap[ast::node_id, vec[constr_def]];
type mt = rec(t ty, ast::mutability mut); type mt = rec(t ty, ast::mutability mut);
@ -257,7 +257,7 @@ tag sty {
ty_char; ty_char;
ty_str; ty_str;
ty_istr; ty_istr;
ty_tag(def_id, t[]); ty_tag(def_id, vec[t]);
ty_box(mt); ty_box(mt);
ty_vec(mt); ty_vec(mt);
ty_ivec(mt); ty_ivec(mt);
@ -267,10 +267,10 @@ tag sty {
ty_task; ty_task;
ty_tup(mt[]); ty_tup(mt[]);
ty_rec(field[]); ty_rec(field[]);
ty_fn(ast::proto, arg[], t, controlflow, (@constr_def)[]); ty_fn(ast::proto, arg[], t, controlflow, vec[@constr_def]);
ty_native_fn(ast::native_abi, arg[], t); ty_native_fn(ast::native_abi, arg[], t);
ty_obj(method[]); ty_obj(vec[method]);
ty_res(def_id, t, t[]); ty_res(def_id, t, vec[t]);
ty_var(int); // type variable ty_var(int); // type variable
ty_param(uint); // fn/tag type param ty_param(uint); // fn/tag type param
ty_type; ty_type;
@ -281,7 +281,7 @@ tag sty {
type constr_def = spanned[constr_general[uint]]; type constr_def = spanned[constr_general[uint]];
type constr_general[T] = type constr_general[T] =
rec(ast::path path, (@constr_arg_general[T])[] args, def_id id); rec(ast::path path, vec[@constr_arg_general[T]] args, def_id id);
// Data structures used in type unification // Data structures used in type unification
@ -351,7 +351,7 @@ const uint idx_first_others = 21u;
type type_store = interner::interner[raw_t]; type type_store = interner::interner[raw_t];
type ty_param_substs_opt_and_ty = tup(option::t[ty::t[]], ty::t); type ty_param_substs_opt_and_ty = tup(option::t[vec[ty::t]], ty::t);
type node_type_table = type node_type_table =
@smallintmap::smallintmap[ty::ty_param_substs_opt_and_ty]; @smallintmap::smallintmap[ty::ty_param_substs_opt_and_ty];
@ -378,7 +378,7 @@ fn populate_type_store(&ctxt cx) {
intern(cx, ty_task, none[str]); intern(cx, ty_task, none[str]);
intern(cx, ty_type, none[str]); intern(cx, ty_type, none[str]);
intern(cx, ty_bot, none[str]); intern(cx, ty_bot, none[str]);
assert (ivec::len(cx.ts.vect) == idx_first_others); assert (vec::len(cx.ts.vect) == idx_first_others);
} }
fn mk_rcache() -> creader_cache { fn mk_rcache() -> creader_cache {
@ -557,7 +557,7 @@ fn mk_str(&ctxt cx) -> t { ret idx_str; }
fn mk_istr(&ctxt cx) -> t { ret idx_istr; } fn mk_istr(&ctxt cx) -> t { ret idx_istr; }
fn mk_tag(&ctxt cx, &ast::def_id did, &t[] tys) -> t { fn mk_tag(&ctxt cx, &ast::def_id did, &vec[t] tys) -> t {
ret gen_ty(cx, ty_tag(did, tys)); ret gen_ty(cx, ty_tag(did, tys));
} }
@ -596,7 +596,7 @@ fn mk_imm_tup(&ctxt cx, &t[] tys) -> t {
fn mk_rec(&ctxt cx, &field[] fs) -> t { ret gen_ty(cx, ty_rec(fs)); } fn mk_rec(&ctxt cx, &field[] fs) -> t { ret gen_ty(cx, ty_rec(fs)); }
fn mk_fn(&ctxt cx, &ast::proto proto, &arg[] args, &t ty, &controlflow cf, fn mk_fn(&ctxt cx, &ast::proto proto, &arg[] args, &t ty, &controlflow cf,
&(@constr_def)[] constrs) -> t { &vec[@constr_def] constrs) -> t {
ret gen_ty(cx, ty_fn(proto, args, ty, cf, constrs)); ret gen_ty(cx, ty_fn(proto, args, ty, cf, constrs));
} }
@ -604,11 +604,11 @@ fn mk_native_fn(&ctxt cx, &ast::native_abi abi, &arg[] args, &t ty) -> t {
ret gen_ty(cx, ty_native_fn(abi, args, ty)); ret gen_ty(cx, ty_native_fn(abi, args, ty));
} }
fn mk_obj(&ctxt cx, &method[] meths) -> t { fn mk_obj(&ctxt cx, &vec[method] meths) -> t {
ret gen_ty(cx, ty_obj(meths)); ret gen_ty(cx, ty_obj(meths));
} }
fn mk_res(&ctxt cx, &ast::def_id did, &t inner, &t[] tps) -> t { fn mk_res(&ctxt cx, &ast::def_id did, &t inner, &vec[t] tps) -> t {
ret gen_ty(cx, ty_res(did, inner, tps)); ret gen_ty(cx, ty_res(did, inner, tps));
} }
@ -753,9 +753,9 @@ fn fold_ty(&ctxt cx, fold_mode fld, t ty_0) -> t {
ty = copy_cname(cx, mk_chan(cx, fold_ty(cx, fld, subty)), ty); ty = copy_cname(cx, mk_chan(cx, fold_ty(cx, fld, subty)), ty);
} }
case (ty_tag(?tid, ?subtys)) { case (ty_tag(?tid, ?subtys)) {
let t[] new_subtys = ~[]; let vec[t] new_subtys = [];
for (t subty in subtys) { for (t subty in subtys) {
new_subtys += ~[fold_ty(cx, fld, subty)]; new_subtys += [fold_ty(cx, fld, subty)];
} }
ty = copy_cname(cx, mk_tag(cx, tid, new_subtys), ty); ty = copy_cname(cx, mk_tag(cx, tid, new_subtys), ty);
} }
@ -799,7 +799,7 @@ fn fold_ty(&ctxt cx, fold_mode fld, t ty_0) -> t {
fold_ty(cx, fld, ret_ty)), ty); fold_ty(cx, fld, ret_ty)), ty);
} }
case (ty_obj(?methods)) { case (ty_obj(?methods)) {
let method[] new_methods = ~[]; let vec[method] new_methods = [];
for (method m in methods) { for (method m in methods) {
let arg[] new_args = ~[]; let arg[] new_args = ~[];
for (arg a in m.inputs) { for (arg a in m.inputs) {
@ -807,18 +807,18 @@ fn fold_ty(&ctxt cx, fold_mode fld, t ty_0) -> t {
ty=fold_ty(cx, fld, a.ty))]; ty=fold_ty(cx, fld, a.ty))];
} }
new_methods += new_methods +=
~[rec(proto=m.proto, [rec(proto=m.proto,
ident=m.ident, ident=m.ident,
inputs=new_args, inputs=new_args,
output=fold_ty(cx, fld, m.output), output=fold_ty(cx, fld, m.output),
cf=m.cf, cf=m.cf,
constrs=m.constrs)]; constrs=m.constrs)];
} }
ty = copy_cname(cx, mk_obj(cx, new_methods), ty); ty = copy_cname(cx, mk_obj(cx, new_methods), ty);
} }
case (ty_res(?did, ?subty, ?tps)) { case (ty_res(?did, ?subty, ?tps)) {
auto new_tps = ~[]; auto new_tps = [];
for (t tp in tps) { new_tps += ~[fold_ty(cx, fld, tp)]; } for (t tp in tps) { new_tps += [fold_ty(cx, fld, tp)]; }
ty = copy_cname(cx, mk_res(cx, did, fold_ty(cx, fld, subty), ty = copy_cname(cx, mk_res(cx, did, fold_ty(cx, fld, subty),
new_tps), ty); new_tps), ty);
} }
@ -1052,12 +1052,8 @@ fn type_has_pointers(&ctxt cx, &t ty) -> bool {
} }
} }
case (ty_res(?did, ?inner, ?tps)) { case (ty_res(?did, ?inner, ?tps)) {
// FIXME: Remove this vec->ivec conversion.
auto tps_ivec = ~[];
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
result = type_has_pointers result = type_has_pointers
(cx, substitute_type_params(cx, tps_ivec, inner)); (cx, substitute_type_params(cx, tps, inner));
} }
case (_) { result = true; } case (_) { result = true; }
} }
@ -1090,7 +1086,7 @@ fn type_has_dynamic_size(&ctxt cx, &t ty) -> bool {
case (ty_istr) { ret false; } case (ty_istr) { ret false; }
case (ty_tag(_, ?subtys)) { case (ty_tag(_, ?subtys)) {
auto i = 0u; auto i = 0u;
while (i < ivec::len[t](subtys)) { while (i < vec::len[t](subtys)) {
if (type_has_dynamic_size(cx, subtys.(i))) { ret true; } if (type_has_dynamic_size(cx, subtys.(i))) { ret true; }
i += 1u; i += 1u;
} }
@ -1244,12 +1240,8 @@ fn type_owns_heap_mem(&ctxt cx, &t ty) -> bool {
} }
} }
case (ty_res(_, ?inner, ?tps)) { case (ty_res(_, ?inner, ?tps)) {
// FIXME: Remove this vec->ivec conversion.
auto tps_ivec = ~[];
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
result = type_owns_heap_mem result = type_owns_heap_mem
(cx, substitute_type_params(cx, tps_ivec, inner)); (cx, substitute_type_params(cx, tps, inner));
} }
case (ty_ptr(_)) { result = false; } case (ty_ptr(_)) { result = false; }
@ -1280,16 +1272,12 @@ fn type_autoderef(&ctxt cx, &ty::t t) -> ty::t {
alt (struct(cx, t1)) { alt (struct(cx, t1)) {
case (ty::ty_box(?mt)) { t1 = mt.ty; } case (ty::ty_box(?mt)) { t1 = mt.ty; }
case (ty::ty_res(_, ?inner, ?tps)) { case (ty::ty_res(_, ?inner, ?tps)) {
// FIXME: Remove this vec->ivec conversion. t1 = substitute_type_params(cx, tps, inner);
auto tps_ivec = ~[];
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
t1 = substitute_type_params(cx, tps_ivec, inner);
} }
case (ty::ty_tag(?did, ?tps)) { case (ty::ty_tag(?did, ?tps)) {
auto variants = tag_variants(cx, did); auto variants = tag_variants(cx, did);
if (ivec::len(variants) != 1u || if (vec::len(variants) != 1u ||
ivec::len(variants.(0).args) != 1u) { vec::len(variants.(0).args) != 1u) {
break; break;
} }
t1 = substitute_type_params(cx, tps, variants.(0).args.(0)); t1 = substitute_type_params(cx, tps, variants.(0).args.(0));
@ -1438,8 +1426,8 @@ fn arg_eq[T](&fn(&T, &T) -> bool eq, @ast::constr_arg_general[T] a,
} }
} }
fn args_eq[T](fn(&T, &T) -> bool eq, &(@ast::constr_arg_general[T])[] a, fn args_eq[T](fn(&T, &T) -> bool eq, vec[@ast::constr_arg_general[T]] a,
&(@ast::constr_arg_general[T])[] b) -> bool { vec[@ast::constr_arg_general[T]] b) -> bool {
let uint i = 0u; let uint i = 0u;
for (@ast::constr_arg_general[T] arg in a) { for (@ast::constr_arg_general[T] arg in a) {
if (!arg_eq(eq, arg, b.(i))) { ret false; } if (!arg_eq(eq, arg, b.(i))) { ret false; }
@ -1454,8 +1442,8 @@ fn constr_eq(&@constr_def c, &@constr_def d) -> bool {
args_eq(eq_int, c.node.args, d.node.args); args_eq(eq_int, c.node.args, d.node.args);
} }
fn constrs_eq(&(@constr_def)[] cs, &(@constr_def)[] ds) -> bool { fn constrs_eq(&vec[@constr_def] cs, &vec[@constr_def] ds) -> bool {
if (ivec::len(cs) != ivec::len(ds)) { ret false; } if (vec::len(cs) != vec::len(ds)) { ret false; }
auto i = 0u; auto i = 0u;
for (@constr_def c in cs) { for (@constr_def c in cs) {
if (!constr_eq(c, ds.(i))) { ret false; } if (!constr_eq(c, ds.(i))) { ret false; }
@ -1526,8 +1514,8 @@ fn equal_type_structures(&sty a, &sty b) -> bool {
alt (b) { alt (b) {
case (ty_tag(?id_b, ?tys_b)) { case (ty_tag(?id_b, ?tys_b)) {
if (!equal_def(id_a, id_b)) { ret false; } if (!equal_def(id_a, id_b)) { ret false; }
auto len = ivec::len[t](tys_a); auto len = vec::len[t](tys_a);
if (len != ivec::len[t](tys_b)) { ret false; } if (len != vec::len[t](tys_b)) { ret false; }
auto i = 0u; auto i = 0u;
while (i < len) { while (i < len) {
if (!eq_ty(tys_a.(i), tys_b.(i))) { ret false; } if (!eq_ty(tys_a.(i), tys_b.(i))) { ret false; }
@ -1634,8 +1622,8 @@ fn equal_type_structures(&sty a, &sty b) -> bool {
case (ty_obj(?methods_a)) { case (ty_obj(?methods_a)) {
alt (b) { alt (b) {
case (ty_obj(?methods_b)) { case (ty_obj(?methods_b)) {
auto len = ivec::len[method](methods_a); auto len = vec::len[method](methods_a);
if (len != ivec::len[method](methods_b)) { ret false; } if (len != vec::len[method](methods_b)) { ret false; }
auto i = 0u; auto i = 0u;
while (i < len) { while (i < len) {
auto m_a = methods_a.(i); auto m_a = methods_a.(i);
@ -1748,16 +1736,16 @@ fn node_id_to_type(&ctxt cx, &ast::node_id id) -> t {
ret node_id_to_ty_param_substs_opt_and_ty(cx, id)._1; ret node_id_to_ty_param_substs_opt_and_ty(cx, id)._1;
} }
fn node_id_to_type_params(&ctxt cx, &ast::node_id id) -> t[] { fn node_id_to_type_params(&ctxt cx, &ast::node_id id) -> vec[t] {
alt (node_id_to_ty_param_substs_opt_and_ty(cx, id)._0) { alt (node_id_to_ty_param_substs_opt_and_ty(cx, id)._0) {
case (none) { ret ~[]; } case (none) { let vec[t] result = []; ret result; }
case (some(?tps)) { ret tps; } case (some(?tps)) { ret tps; }
} }
} }
fn node_id_has_type_params(&ctxt cx, &ast::node_id id) -> bool { fn node_id_has_type_params(&ctxt cx, &ast::node_id id) -> bool {
auto tpt = node_id_to_ty_param_substs_opt_and_ty(cx, id); auto tpt = node_id_to_ty_param_substs_opt_and_ty(cx, id);
ret !option::is_none[t[]](tpt._0); ret !option::is_none[vec[t]](tpt._0);
} }
@ -1767,13 +1755,7 @@ fn ty_param_substs_opt_and_ty_to_monotype(&ctxt cx,
t { t {
alt (tpot._0) { alt (tpot._0) {
case (none) { ret tpot._1; } case (none) { ret tpot._1; }
case (some(?tps)) { case (some(?tps)) { ret substitute_type_params(cx, tps, tpot._1); }
// FIXME: Remove this vec->ivec conversion.
auto tps_ivec = ~[];
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
ret substitute_type_params(cx, tps_ivec, tpot._1);
}
} }
} }
@ -1788,22 +1770,24 @@ fn node_id_to_monotype(&ctxt cx, ast::node_id id) -> t {
// Returns the number of distinct type parameters in the given type. // Returns the number of distinct type parameters in the given type.
fn count_ty_params(&ctxt cx, t ty) -> uint { fn count_ty_params(&ctxt cx, t ty) -> uint {
fn counter(&ctxt cx, @mutable (uint[]) param_indices, t ty) { fn counter(&ctxt cx, @mutable vec[uint] param_indices, t ty) {
alt (struct(cx, ty)) { alt (struct(cx, ty)) {
case (ty_param(?param_idx)) { case (ty_param(?param_idx)) {
auto seen = false; auto seen = false;
for (uint other_param_idx in *param_indices) { for (uint other_param_idx in *param_indices) {
if (param_idx == other_param_idx) { seen = true; } if (param_idx == other_param_idx) { seen = true; }
} }
if (!seen) { *param_indices += ~[param_idx]; } if (!seen) { *param_indices += [param_idx]; }
} }
case (_) {/* fall through */ } case (_) {/* fall through */ }
} }
} }
let @mutable (uint[]) param_indices = @mutable ~[]; let vec[uint] v = []; // FIXME: typechecker botch
let @mutable vec[uint] param_indices = @mutable v;
auto f = bind counter(cx, param_indices, _); auto f = bind counter(cx, param_indices, _);
walk_ty(cx, f, ty); walk_ty(cx, f, ty);
ret ivec::len[uint](*param_indices); ret vec::len[uint](*param_indices);
} }
fn type_contains_vars(&ctxt cx, &t typ) -> bool { fn type_contains_vars(&ctxt cx, &t typ) -> bool {
@ -1881,7 +1865,7 @@ fn expr_ty(&ctxt cx, &@ast::expr expr) -> t {
ret node_id_to_monotype(cx, expr.id); ret node_id_to_monotype(cx, expr.id);
} }
fn expr_ty_params_and_ty(&ctxt cx, &@ast::expr expr) -> tup(t[], t) { fn expr_ty_params_and_ty(&ctxt cx, &@ast::expr expr) -> tup(vec[t], t) {
ret tup(node_id_to_type_params(cx, expr.id), ret tup(node_id_to_type_params(cx, expr.id),
node_id_to_type(cx, expr.id)); node_id_to_type(cx, expr.id));
} }
@ -1941,17 +1925,17 @@ fn field_idx(&session::session sess, &span sp, &ast::ident id,
} }
fn method_idx(&session::session sess, &span sp, &ast::ident id, fn method_idx(&session::session sess, &span sp, &ast::ident id,
&method[] meths) -> uint { &vec[method] meths) -> uint {
let uint i = 0u; let uint i = 0u;
for (method m in meths) { if (str::eq(m.ident, id)) { ret i; } i += 1u; } for (method m in meths) { if (str::eq(m.ident, id)) { ret i; } i += 1u; }
sess.span_fatal(sp, "unknown method '" + id + "' of obj"); sess.span_fatal(sp, "unknown method '" + id + "' of obj");
} }
fn sort_methods(&method[] meths) -> method[] { fn sort_methods(&vec[method] meths) -> vec[method] {
fn method_lteq(&method a, &method b) -> bool { fn method_lteq(&method a, &method b) -> bool {
ret str::lteq(a.ident, b.ident); ret str::lteq(a.ident, b.ident);
} }
ret std::sort::ivector::merge_sort[method](bind method_lteq(_, _), meths); ret std::sort::merge_sort[method](bind method_lteq(_, _), meths);
} }
fn is_lval(&@ast::expr expr) -> bool { fn is_lval(&@ast::expr expr) -> bool {
@ -2137,8 +2121,8 @@ mod unify {
&t expected, &t actual, &arg[] expected_inputs, &t expected, &t actual, &arg[] expected_inputs,
&t expected_output, &arg[] actual_inputs, &t actual_output, &t expected_output, &arg[] actual_inputs, &t actual_output,
&controlflow expected_cf, &controlflow actual_cf, &controlflow expected_cf, &controlflow actual_cf,
&(@constr_def)[] expected_constrs, &vec[@constr_def] expected_constrs,
&(@constr_def)[] actual_constrs) -> result { &vec[@constr_def] actual_constrs) -> result {
if (e_proto != a_proto) { ret ures_err(terr_mismatch); } if (e_proto != a_proto) { ret ures_err(terr_mismatch); }
alt (expected_cf) { alt (expected_cf) {
case (ast::return) { } case (ast::return) { }
@ -2191,12 +2175,12 @@ mod unify {
} }
} }
fn unify_obj(&@ctxt cx, &t expected, &t actual, fn unify_obj(&@ctxt cx, &t expected, &t actual,
&method[] expected_meths, &method[] actual_meths) -> &vec[method] expected_meths, &vec[method] actual_meths) ->
result { result {
let method[] result_meths = ~[]; let vec[method] result_meths = [];
let uint i = 0u; let uint i = 0u;
let uint expected_len = ivec::len[method](expected_meths); let uint expected_len = vec::len[method](expected_meths);
let uint actual_len = ivec::len[method](actual_meths); let uint actual_len = vec::len[method](actual_meths);
if (expected_len != actual_len) { ret ures_err(terr_meth_count); } if (expected_len != actual_len) { ret ures_err(terr_meth_count); }
while (i < expected_len) { while (i < expected_len) {
auto e_meth = expected_meths.(i); auto e_meth = expected_meths.(i);
@ -2214,10 +2198,10 @@ mod unify {
alt (struct(cx.tcx, tfn)) { alt (struct(cx.tcx, tfn)) {
case (ty_fn(?proto, ?ins, ?out, ?cf, ?constrs)) { case (ty_fn(?proto, ?ins, ?out, ?cf, ?constrs)) {
result_meths += result_meths +=
~[rec(inputs=ins, [rec(inputs=ins,
output=out, output=out,
cf=cf, cf=cf,
constrs=constrs with e_meth)]; constrs=constrs with e_meth)];
} }
} }
} }
@ -2344,16 +2328,18 @@ mod unify {
// TODO: factor this cruft out, see the TODO in the // TODO: factor this cruft out, see the TODO in the
// ty::ty_tup case // ty::ty_tup case
let t[] result_tps = ~[]; let vec[t] result_tps = [];
auto i = 0u; auto i = 0u;
auto expected_len = ivec::len[t](expected_tps); auto expected_len = vec::len[t](expected_tps);
while (i < expected_len) { while (i < expected_len) {
auto expected_tp = expected_tps.(i); auto expected_tp = expected_tps.(i);
auto actual_tp = actual_tps.(i); auto actual_tp = actual_tps.(i);
auto result = auto result =
unify_step(cx, expected_tp, actual_tp); unify_step(cx, expected_tp, actual_tp);
alt (result) { alt (result) {
case (ures_ok(?rty)) { result_tps += ~[rty]; } case (ures_ok(?rty)) {
vec::push[t](result_tps, rty);
}
case (_) { ret result; } case (_) { ret result; }
} }
i += 1u; i += 1u;
@ -2473,13 +2459,13 @@ mod unify {
alt (result) { alt (result) {
case (ures_ok(?res_inner)) { case (ures_ok(?res_inner)) {
auto i = 0u; auto i = 0u;
auto res_tps = ~[]; auto res_tps = [];
for (t ex_tp in ex_tps) { for (t ex_tp in ex_tps) {
auto result = auto result =
unify_step(cx, ex_tp, act_tps.(i)); unify_step(cx, ex_tp, act_tps.(i));
alt (result) { alt (result) {
case (ures_ok(?rty)) { case (ures_ok(?rty)) {
res_tps += ~[rty]; vec::push(res_tps, rty);
} }
case (_) { ret result; } case (_) { ret result; }
} }
@ -2761,16 +2747,13 @@ fn type_err_to_str(&ty::type_err err) -> str {
// Converts type parameters in a type to type variables and returns the // Converts type parameters in a type to type variables and returns the
// resulting type along with a list of type variable IDs. // resulting type along with a list of type variable IDs.
fn bind_params_in_type(&span sp, &ctxt cx, fn() -> int next_ty_var, t typ, fn bind_params_in_type(&span sp, &ctxt cx, fn() -> int next_ty_var, t typ,
uint ty_param_count) -> tup(int[], t) { uint ty_param_count) -> tup(vec[int], t) {
let @mutable int[] param_var_ids = @mutable ~[]; let vec[int] param_var_ids = [];
auto i = 0u; auto i = 0u;
while (i < ty_param_count) { while (i < ty_param_count) { param_var_ids += [next_ty_var()]; i += 1u; }
*param_var_ids += ~[next_ty_var()]; fn binder(span sp, ctxt cx, vec[int] param_var_ids,
i += 1u;
}
fn binder(span sp, ctxt cx, @mutable int[] param_var_ids,
fn() -> int next_ty_var, uint index) -> t { fn() -> int next_ty_var, uint index) -> t {
if (index < ivec::len(*param_var_ids)) { if (index < vec::len(param_var_ids)) {
ret mk_var(cx, param_var_ids.(index)); ret mk_var(cx, param_var_ids.(index));
} }
else { else {
@ -2780,19 +2763,20 @@ fn bind_params_in_type(&span sp, &ctxt cx, fn() -> int next_ty_var, t typ,
auto new_typ = auto new_typ =
fold_ty(cx, fm_param(bind binder(sp, cx, param_var_ids, fold_ty(cx, fm_param(bind binder(sp, cx, param_var_ids,
next_ty_var, _)), typ); next_ty_var, _)), typ);
ret tup(*param_var_ids, new_typ); ret tup(param_var_ids, new_typ);
} }
// Replaces type parameters in the given type using the given list of // Replaces type parameters in the given type using the given list of
// substitions. // substitions.
fn substitute_type_params(&ctxt cx, &ty::t[] substs, t typ) -> t { fn substitute_type_params(&ctxt cx, vec[ty::t] substs, t typ) -> t {
if (!type_contains_params(cx, typ)) { ret typ; } if (!type_contains_params(cx, typ)) { ret typ; }
fn substituter(ctxt cx, @ty::t[] substs, uint idx) -> t { fn substituter(ctxt cx, vec[ty::t] substs, uint idx) -> t {
// FIXME: bounds check can fail // FIXME: bounds check can fail
ret substs.(idx); ret substs.(idx);
} }
ret fold_ty(cx, fm_param(bind substituter(cx, @substs, _)), typ); ret fold_ty(cx, fm_param(bind substituter(cx, substs, _)), typ);
} }
fn def_has_ty_params(&ast::def def) -> bool { fn def_has_ty_params(&ast::def def) -> bool {
@ -2815,10 +2799,12 @@ fn def_has_ty_params(&ast::def def) -> bool {
// Tag information // Tag information
type variant_info = rec(ty::t[] args, ty::t ctor_ty, ast::def_id id); type variant_info = rec(vec[ty::t] args, ty::t ctor_ty, ast::def_id id);
fn tag_variants(&ctxt cx, &ast::def_id id) -> variant_info[] { fn tag_variants(&ctxt cx, &ast::def_id id) -> vec[variant_info] {
if (ast::local_crate != id._0) { ret decoder::get_tag_variants(cx, id); } if (ast::local_crate != id._0) {
ret decoder::get_tag_variants(cx, id);
}
auto item = alt (cx.items.find(id._1)) { auto item = alt (cx.items.find(id._1)) {
case (some(?i)) { i } case (some(?i)) { i }
case (none) { case (none) {
@ -2829,22 +2815,22 @@ fn tag_variants(&ctxt cx, &ast::def_id id) -> variant_info[] {
case (ast_map::node_item(?item)) { case (ast_map::node_item(?item)) {
alt (item.node) { alt (item.node) {
case (ast::item_tag(?variants, _)) { case (ast::item_tag(?variants, _)) {
let variant_info[] result = ~[]; let vec[variant_info] result = [];
for (ast::variant variant in variants) { for (ast::variant variant in variants) {
auto ctor_ty = node_id_to_monotype auto ctor_ty = node_id_to_monotype
(cx, variant.node.id); (cx, variant.node.id);
let t[] arg_tys = ~[]; let vec[t] arg_tys = [];
if (vec::len[ast::variant_arg](variant.node.args) > if (vec::len[ast::variant_arg](variant.node.args) >
0u) { 0u) {
for (arg a in ty_fn_args(cx, ctor_ty)) { for (arg a in ty_fn_args(cx, ctor_ty)) {
arg_tys += ~[a.ty]; arg_tys += [a.ty];
} }
} }
auto did = variant.node.id; auto did = variant.node.id;
result += result +=
~[rec(args=arg_tys, [rec(args=arg_tys,
ctor_ty=ctor_ty, ctor_ty=ctor_ty,
id=ast::local_def(did))]; id=ast::local_def(did))];
} }
ret result; ret result;
} }
@ -2859,7 +2845,7 @@ fn tag_variant_with_id(&ctxt cx, &ast::def_id tag_id, &ast::def_id variant_id)
-> variant_info { -> variant_info {
auto variants = tag_variants(cx, tag_id); auto variants = tag_variants(cx, tag_id);
auto i = 0u; auto i = 0u;
while (i < ivec::len[variant_info](variants)) { while (i < vec::len[variant_info](variants)) {
auto variant = variants.(i); auto variant = variants.(i);
if (def_eq(variant.id, variant_id)) { ret variant; } if (def_eq(variant.id, variant_id)) { ret variant; }
i += 1u; i += 1u;

View file

@ -155,9 +155,9 @@ fn instantiate_path(&@fn_ctxt fcx, &ast::path pth, &ty_param_count_and_ty tpt,
ty_param_count); ty_param_count);
auto ty_param_vars = bind_result._0; auto ty_param_vars = bind_result._0;
auto ty_substs_opt; auto ty_substs_opt;
auto ty_substs_len = ivec::len[@ast::ty](pth.node.types); auto ty_substs_len = vec::len[@ast::ty](pth.node.types);
if (ty_substs_len > 0u) { if (ty_substs_len > 0u) {
let ty::t[] ty_substs = ~[]; let vec[ty::t] ty_substs = [];
auto i = 0u; auto i = 0u;
while (i < ty_substs_len) { while (i < ty_substs_len) {
// TODO: Report an error if the number of type params in the item // TODO: Report an error if the number of type params in the item
@ -166,10 +166,10 @@ fn instantiate_path(&@fn_ctxt fcx, &ast::path pth, &ty_param_count_and_ty tpt,
auto ty_var = ty::mk_var(fcx.ccx.tcx, ty_param_vars.(i)); auto ty_var = ty::mk_var(fcx.ccx.tcx, ty_param_vars.(i));
auto ty_subst = ast_ty_to_ty_crate(fcx.ccx, pth.node.types.(i)); auto ty_subst = ast_ty_to_ty_crate(fcx.ccx, pth.node.types.(i));
auto res_ty = demand::simple(fcx, pth.span, ty_var, ty_subst); auto res_ty = demand::simple(fcx, pth.span, ty_var, ty_subst);
ty_substs += ~[res_ty]; ty_substs += [res_ty];
i += 1u; i += 1u;
} }
ty_substs_opt = some[ty::t[]](ty_substs); ty_substs_opt = some[vec[ty::t]](ty_substs);
if (ty_param_count == 0u) { if (ty_param_count == 0u) {
fcx.ccx.tcx.sess.span_fatal(sp, fcx.ccx.tcx.sess.span_fatal(sp,
"this item does not take type " + "this item does not take type " +
@ -179,13 +179,13 @@ fn instantiate_path(&@fn_ctxt fcx, &ast::path pth, &ty_param_count_and_ty tpt,
} else { } else {
// We will acquire the type parameters through unification. // We will acquire the type parameters through unification.
let ty::t[] ty_substs = ~[]; let vec[ty::t] ty_substs = [];
auto i = 0u; auto i = 0u;
while (i < ty_param_count) { while (i < ty_param_count) {
ty_substs += ~[ty::mk_var(fcx.ccx.tcx, ty_param_vars.(i))]; ty_substs += [ty::mk_var(fcx.ccx.tcx, ty_param_vars.(i))];
i += 1u; i += 1u;
} }
ty_substs_opt = some[ty::t[]](ty_substs); ty_substs_opt = some[vec[ty::t]](ty_substs);
} }
ret tup(ty_substs_opt, tpt._1); ret tup(ty_substs_opt, tpt._1);
} }
@ -256,7 +256,7 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
ret rec(ty=ast_ty_to_ty(tcx, getter, mt.ty), mut=mt.mut); ret rec(ty=ast_ty_to_ty(tcx, getter, mt.ty), mut=mt.mut);
} }
fn instantiate(&ty::ctxt tcx, &span sp, &ty_getter getter, fn instantiate(&ty::ctxt tcx, &span sp, &ty_getter getter,
&ast::def_id id, &(@ast::ty)[] args) -> ty::t { &ast::def_id id, &vec[@ast::ty] args) -> ty::t {
// TODO: maybe record cname chains so we can do // TODO: maybe record cname chains so we can do
// "foo = int" like OCaml? // "foo = int" like OCaml?
@ -265,11 +265,11 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
// The typedef is type-parametric. Do the type substitution. // The typedef is type-parametric. Do the type substitution.
// //
let ty::t[] param_bindings = ~[]; let vec[ty::t] param_bindings = [];
for (@ast::ty ast_ty in args) { for (@ast::ty ast_ty in args) {
param_bindings += ~[ast_ty_to_ty(tcx, getter, ast_ty)]; param_bindings += [ast_ty_to_ty(tcx, getter, ast_ty)];
} }
if (ivec::len(param_bindings) != if (vec::len(param_bindings) !=
ty::count_ty_params(tcx, params_opt_and_ty._1)) { ty::count_ty_params(tcx, params_opt_and_ty._1)) {
tcx.sess.span_fatal(sp, tcx.sess.span_fatal(sp,
"Wrong number of type arguments for a" + "Wrong number of type arguments for a" +
@ -335,17 +335,17 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
} }
auto out_ty = ast_ty_to_ty(tcx, getter, output); auto out_ty = ast_ty_to_ty(tcx, getter, output);
auto out_constrs = ~[]; let fn(&@ast::constr) -> @ty::constr_def g =
for (@ast::constr constr in constrs) { bind ast_constr_to_constr(tcx, _);
out_constrs += ~[ast_constr_to_constr(tcx, constr)]; let vec[@ty::constr_def] out_constrs = vec::map(g, constrs);
}
typ = ty::mk_fn(tcx, proto, i, out_ty, cf, out_constrs); typ = ty::mk_fn(tcx, proto, i, out_ty, cf, out_constrs);
} }
case (ast::ty_path(?path, ?id)) { case (ast::ty_path(?path, ?id)) {
alt (tcx.def_map.find(id)) { alt (tcx.def_map.find(id)) {
case (some(ast::def_ty(?id))) { case (some(ast::def_ty(?id))) {
typ = instantiate(tcx, ast_ty.span, getter, id, typ =
path.node.types); instantiate(tcx, ast_ty.span, getter, id,
path.node.types);
} }
case (some(ast::def_native_ty(?id))) { typ = getter(id)._1; } case (some(ast::def_native_ty(?id))) { typ = getter(id)._1; }
case (some(ast::def_ty_arg(?id))) { case (some(ast::def_ty_arg(?id))) {
@ -363,7 +363,7 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
cname = some(path_to_str(path)); cname = some(path_to_str(path));
} }
case (ast::ty_obj(?meths)) { case (ast::ty_obj(?meths)) {
let ty::method[] tmeths = ~[]; let vec[ty::method] tmeths = [];
for (ast::ty_method m in meths) { for (ast::ty_method m in meths) {
auto ins = ~[]; auto ins = ~[];
for (ast::ty_arg ta in m.node.inputs) { for (ast::ty_arg ta in m.node.inputs) {
@ -371,10 +371,10 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
} }
auto out = ast_ty_to_ty(tcx, getter, m.node.output); auto out = ast_ty_to_ty(tcx, getter, m.node.output);
auto out_constrs = ~[]; let fn(&@ast::constr) -> @ty::constr_def g =
for (@ast::constr constr in m.node.constrs) { bind ast_constr_to_constr(tcx, _);
out_constrs += ~[ast_constr_to_constr(tcx, constr)]; let vec[@ty::constr_def] out_constrs =
} vec::map(g, m.node.constrs);
let ty::method new_m = let ty::method new_m =
rec(proto=m.node.proto, rec(proto=m.node.proto,
ident=m.node.ident, ident=m.node.ident,
@ -382,7 +382,7 @@ fn ast_ty_to_ty(&ty::ctxt tcx, &ty_getter getter, &@ast::ty ast_ty) -> ty::t {
output=out, output=out,
cf=m.node.cf, cf=m.node.cf,
constrs=out_constrs); constrs=out_constrs);
tmeths += ~[new_m]; vec::push[ty::method](tmeths, new_m);
} }
typ = ty::mk_obj(tcx, ty::sort_methods(tmeths)); typ = ty::mk_obj(tcx, ty::sort_methods(tmeths));
} }
@ -434,23 +434,23 @@ mod write {
// Writes a type with no type parameters into the node type table. // Writes a type with no type parameters into the node type table.
fn ty_only(&ty::ctxt tcx, ast::node_id node_id, ty::t typ) { fn ty_only(&ty::ctxt tcx, ast::node_id node_id, ty::t typ) {
ret ty(tcx, node_id, tup(none[ty::t[]], typ)); ret ty(tcx, node_id, tup(none[vec[ty::t]], typ));
} }
// Writes a type with no type parameters into the node type table. This // Writes a type with no type parameters into the node type table. This
// function allows for the possibility of type variables. // function allows for the possibility of type variables.
fn ty_only_fixup(@fn_ctxt fcx, ast::node_id node_id, ty::t typ) { fn ty_only_fixup(@fn_ctxt fcx, ast::node_id node_id, ty::t typ) {
ret ty_fixup(fcx, node_id, tup(none[ty::t[]], typ)); ret ty_fixup(fcx, node_id, tup(none[vec[ty::t]], typ));
} }
// Writes a nil type into the node type table. // Writes a nil type into the node type table.
fn nil_ty(&ty::ctxt tcx, ast::node_id node_id) { fn nil_ty(&ty::ctxt tcx, ast::node_id node_id) {
ret ty(tcx, node_id, tup(none[ty::t[]], ty::mk_nil(tcx))); ret ty(tcx, node_id, tup(none[vec[ty::t]], ty::mk_nil(tcx)));
} }
// Writes the bottom type into the node type table. // Writes the bottom type into the node type table.
fn bot_ty(&ty::ctxt tcx, ast::node_id node_id) { fn bot_ty(&ty::ctxt tcx, ast::node_id node_id) {
ret ty(tcx, node_id, tup(none[ty::t[]], ty::mk_bot(tcx))); ret ty(tcx, node_id, tup(none[vec[ty::t]], ty::mk_bot(tcx)));
} }
} }
@ -472,11 +472,11 @@ mod write {
mod collect { mod collect {
type ctxt = rec(ty::ctxt tcx); type ctxt = rec(ty::ctxt tcx);
fn mk_ty_params(&@ctxt cx, uint n) -> ty::t[] { fn mk_ty_params(&@ctxt cx, uint n) -> vec[ty::t] {
auto tps = ~[]; auto tps = [];
auto i = 0u; auto i = 0u;
while (i < n) { while (i < n) {
tps += ~[ty::mk_param(cx.tcx, i)]; tps += [ty::mk_param(cx.tcx, i)];
i += 1u; i += 1u;
} }
ret tps; ret tps;
@ -490,10 +490,9 @@ mod collect {
for (ast::arg a in decl.inputs) { input_tys += ~[ty_of_arg(a)]; } for (ast::arg a in decl.inputs) { input_tys += ~[ty_of_arg(a)]; }
auto output_ty = convert(decl.output); auto output_ty = convert(decl.output);
auto out_constrs = ~[]; let fn(&@ast::constr) -> @ty::constr_def g =
for (@ast::constr constr in decl.constraints) { bind ast_constr_to_constr(cx.tcx, _);
out_constrs += ~[ast_constr_to_constr(cx.tcx, constr)]; let vec[@ty::constr_def] out_constrs = vec::map(g, decl.constraints);
}
auto t_fn = auto t_fn =
ty::mk_fn(cx.tcx, proto, input_tys, output_ty, decl.cf, ty::mk_fn(cx.tcx, proto, input_tys, output_ty, decl.cf,
out_constrs); out_constrs);
@ -569,11 +568,10 @@ mod collect {
} }
auto output = convert(m.node.meth.decl.output); auto output = convert(m.node.meth.decl.output);
let fn(&@ast::constr) -> @ty::constr_def g =
auto out_constrs = ~[]; bind ast_constr_to_constr(cx.tcx, _);
for (@ast::constr constr in m.node.meth.decl.constraints) { let vec[@ty::constr_def] out_constrs =
out_constrs += ~[ast_constr_to_constr(cx.tcx, constr)]; vec::map(g, m.node.meth.decl.constraints);
}
ret rec(proto=m.node.meth.proto, ident=m.node.ident, ret rec(proto=m.node.meth.proto, ident=m.node.ident,
inputs=inputs, output=output, cf=m.node.meth.decl.cf, inputs=inputs, output=output, cf=m.node.meth.decl.cf,
constrs=out_constrs); constrs=out_constrs);
@ -598,7 +596,7 @@ mod collect {
} }
auto t_fn = ty::mk_fn(cx.tcx, ast::proto_fn, t_inputs, t_obj._1, auto t_fn = ty::mk_fn(cx.tcx, ast::proto_fn, t_inputs, t_obj._1,
ast::return, ~[]); ast::return, []);
auto tpt = tup(t_obj._0, t_fn); auto tpt = tup(t_obj._0, t_fn);
cx.tcx.tcache.insert(local_def(ctor_id), tpt); cx.tcx.tcache.insert(local_def(ctor_id), tpt);
ret tpt; ret tpt;
@ -649,8 +647,7 @@ mod collect {
// Create a new generic polytype. // Create a new generic polytype.
auto ty_param_count = vec::len[ast::ty_param](tps); auto ty_param_count = vec::len[ast::ty_param](tps);
let vec[ty::t] subtys = mk_ty_params(cx, ty_param_count);
let ty::t[] subtys = mk_ty_params(cx, ty_param_count);
auto t = ty::mk_tag(cx.tcx, local_def(it.id), subtys); auto t = ty::mk_tag(cx.tcx, local_def(it.id), subtys);
auto tpt = tup(ty_param_count, t); auto tpt = tup(ty_param_count, t);
cx.tcx.tcache.insert(local_def(it.id), tpt); cx.tcx.tcache.insert(local_def(it.id), tpt);
@ -688,7 +685,7 @@ mod collect {
// Create a set of parameter types shared among all the variants. // Create a set of parameter types shared among all the variants.
auto ty_param_count = vec::len[ast::ty_param](ty_params); auto ty_param_count = vec::len[ast::ty_param](ty_params);
let ty::t[] ty_param_tys = mk_ty_params(cx, ty_param_count); let vec[ty::t] ty_param_tys = mk_ty_params(cx, ty_param_count);
for (ast::variant variant in variants) { for (ast::variant variant in variants) {
// Nullary tag constructors get turned into constants; n-ary tag // Nullary tag constructors get turned into constants; n-ary tag
// constructors get turned into functions. // constructors get turned into functions.
@ -709,19 +706,16 @@ mod collect {
auto tag_t = ty::mk_tag(cx.tcx, tag_id, ty_param_tys); auto tag_t = ty::mk_tag(cx.tcx, tag_id, ty_param_tys);
// FIXME: this will be different for constrained types // FIXME: this will be different for constrained types
result_ty = ty::mk_fn(cx.tcx, ast::proto_fn, args, tag_t, result_ty = ty::mk_fn(cx.tcx, ast::proto_fn, args, tag_t,
ast::return, ~[]); ast::return, []);
} }
auto tpt = tup(ty_param_count, result_ty); auto tpt = tup(ty_param_count, result_ty);
cx.tcx.tcache.insert(local_def(variant.node.id), tpt); cx.tcx.tcache.insert(local_def(variant.node.id), tpt);
write::ty_only(cx.tcx, variant.node.id, result_ty); write::ty_only(cx.tcx, variant.node.id, result_ty);
} }
} }
fn get_obj_method_types(&@ctxt cx, &ast::_obj object) -> ty::method[] { fn get_obj_method_types(&@ctxt cx, &ast::_obj object) -> vec[ty::method] {
auto meths = ~[]; ret vec::map[@ast::method,
for (@ast::method m in object.methods) { method](bind ty_of_method(cx, _), object.methods);
meths += ~[ty_of_method(cx, m)];
}
ret meths;
} }
fn convert(@ctxt cx, @mutable option::t[ast::native_abi] abi, fn convert(@ctxt cx, @mutable option::t[ast::native_abi] abi,
&@ast::item it) { &@ast::item it) {
@ -783,7 +777,7 @@ mod collect {
case (none) {/* nothing to do */ } case (none) {/* nothing to do */ }
case (some(?m)) { case (some(?m)) {
auto t = ty::mk_fn(cx.tcx, ast::proto_fn, ~[], auto t = ty::mk_fn(cx.tcx, ast::proto_fn, ~[],
ty::mk_nil(cx.tcx), ast::return, ~[]); ty::mk_nil(cx.tcx), ast::return, []);
write::ty_only(cx.tcx, m.node.id, t); write::ty_only(cx.tcx, m.node.id, t);
} }
} }
@ -793,9 +787,9 @@ mod collect {
auto t_res = ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty, auto t_res = ty::mk_res(cx.tcx, local_def(it.id), t_arg.ty,
mk_ty_params(cx, vec::len(tps))); mk_ty_params(cx, vec::len(tps)));
auto t_ctor = ty::mk_fn(cx.tcx, ast::proto_fn, ~[t_arg], auto t_ctor = ty::mk_fn(cx.tcx, ast::proto_fn, ~[t_arg],
t_res, ast::return, ~[]); t_res, ast::return, []);
auto t_dtor = ty::mk_fn(cx.tcx, ast::proto_fn, ~[t_arg], auto t_dtor = ty::mk_fn(cx.tcx, ast::proto_fn, ~[t_arg],
ty::mk_nil(cx.tcx), ast::return, ~[]); ty::mk_nil(cx.tcx), ast::return, []);
write::ty_only(cx.tcx, it.id, t_res); write::ty_only(cx.tcx, it.id, t_res);
write::ty_only(cx.tcx, ctor_id, t_ctor); write::ty_only(cx.tcx, ctor_id, t_ctor);
cx.tcx.tcache.insert(local_def(ctor_id), cx.tcx.tcache.insert(local_def(ctor_id),
@ -865,16 +859,12 @@ fn do_autoderef(&@fn_ctxt fcx, &span sp, &ty::t t) -> ty::t {
alt (structure_of(fcx, sp, t1)) { alt (structure_of(fcx, sp, t1)) {
case (ty::ty_box(?inner)) { t1 = inner.ty; } case (ty::ty_box(?inner)) { t1 = inner.ty; }
case (ty::ty_res(_, ?inner, ?tps)) { case (ty::ty_res(_, ?inner, ?tps)) {
// FIXME: Remove this vec->ivec conversion. t1 = ty::substitute_type_params(fcx.ccx.tcx, tps, inner);
auto tps_ivec = ~[];
for (ty::t tp in tps) { tps_ivec += ~[tp]; }
t1 = ty::substitute_type_params(fcx.ccx.tcx, tps_ivec, inner);
} }
case (ty::ty_tag(?did, ?tps)) { case (ty::ty_tag(?did, ?tps)) {
auto variants = ty::tag_variants(fcx.ccx.tcx, did); auto variants = ty::tag_variants(fcx.ccx.tcx, did);
if (ivec::len(variants) != 1u || if (vec::len(variants) != 1u ||
ivec::len(variants.(0).args) != 1u) { vec::len(variants.(0).args) != 1u) {
ret t1; ret t1;
} }
t1 = ty::substitute_type_params(fcx.ccx.tcx, tps, t1 = ty::substitute_type_params(fcx.ccx.tcx, tps,
@ -914,22 +904,24 @@ fn resolve_type_vars_if_possible(&@fn_ctxt fcx, ty::t typ) -> ty::t {
// Demands - procedures that require that two types unify and emit an error // Demands - procedures that require that two types unify and emit an error
// message if they don't. // message if they don't.
type ty_param_substs_and_ty = tup(ty::t[], ty::t); type ty_param_substs_and_ty = tup(vec[ty::t], ty::t);
mod demand { mod demand {
fn simple(&@fn_ctxt fcx, &span sp, &ty::t expected, &ty::t actual) -> fn simple(&@fn_ctxt fcx, &span sp, &ty::t expected, &ty::t actual) ->
ty::t { ty::t {
ret full(fcx, sp, expected, actual, ~[], NO_AUTODEREF)._1; let vec[ty::t] tps = [];
ret full(fcx, sp, expected, actual, tps, NO_AUTODEREF)._1;
} }
fn autoderef(&@fn_ctxt fcx, &span sp, &ty::t expected, &ty::t actual, fn autoderef(&@fn_ctxt fcx, &span sp, &ty::t expected, &ty::t actual,
autoderef_kind adk) -> ty::t { autoderef_kind adk) -> ty::t {
ret full(fcx, sp, expected, actual, ~[], adk)._1; let vec[ty::t] tps = [];
ret full(fcx, sp, expected, actual, tps, adk)._1;
} }
// Requires that the two types unify, and prints an error message if they // Requires that the two types unify, and prints an error message if they
// don't. Returns the unified type and the type parameter substitutions. // don't. Returns the unified type and the type parameter substitutions.
fn full(&@fn_ctxt fcx, &span sp, &ty::t expected, &ty::t actual, fn full(&@fn_ctxt fcx, &span sp, &ty::t expected, &ty::t actual,
&ty::t[] ty_param_substs_0, autoderef_kind adk) -> &vec[ty::t] ty_param_substs_0, autoderef_kind adk) ->
ty_param_substs_and_ty { ty_param_substs_and_ty {
auto expected_1 = expected; auto expected_1 = expected;
auto actual_1 = actual; auto actual_1 = actual;
@ -954,10 +946,10 @@ mod demand {
fn mk_result(&@fn_ctxt fcx, &ty::t result_ty, fn mk_result(&@fn_ctxt fcx, &ty::t result_ty,
&vec[int] ty_param_subst_var_ids, &vec[int] ty_param_subst_var_ids,
uint implicit_boxes) -> ty_param_substs_and_ty { uint implicit_boxes) -> ty_param_substs_and_ty {
let ty::t[] result_ty_param_substs = ~[]; let vec[ty::t] result_ty_param_substs = [];
for (int var_id in ty_param_subst_var_ids) { for (int var_id in ty_param_subst_var_ids) {
auto tp_subst = ty::mk_var(fcx.ccx.tcx, var_id); auto tp_subst = ty::mk_var(fcx.ccx.tcx, var_id);
result_ty_param_substs += ~[tp_subst]; result_ty_param_substs += [tp_subst];
} }
ret tup(result_ty_param_substs, ret tup(result_ty_param_substs,
add_boxes(fcx.ccx, implicit_boxes, result_ty)); add_boxes(fcx.ccx, implicit_boxes, result_ty));
@ -997,7 +989,7 @@ fn are_compatible(&@fn_ctxt fcx, &ty::t expected, &ty::t actual) -> bool {
// Returns the types of the arguments to a tag variant. // Returns the types of the arguments to a tag variant.
fn variant_arg_types(&@crate_ctxt ccx, &span sp, &ast::def_id vid, fn variant_arg_types(&@crate_ctxt ccx, &span sp, &ast::def_id vid,
&ty::t[] tag_ty_params) -> vec[ty::t] { &vec[ty::t] tag_ty_params) -> vec[ty::t] {
let vec[ty::t] result = []; let vec[ty::t] result = [];
auto tpt = ty::lookup_item_type(ccx.tcx, vid); auto tpt = ty::lookup_item_type(ccx.tcx, vid);
alt (ty::struct(ccx.tcx, tpt._1)) { alt (ty::struct(ccx.tcx, tpt._1)) {
@ -1047,14 +1039,13 @@ mod writeback {
auto new_ty = resolve_type_vars_in_type(fcx, sp, tpot._1); auto new_ty = resolve_type_vars_in_type(fcx, sp, tpot._1);
auto new_substs_opt; auto new_substs_opt;
alt (tpot._0) { alt (tpot._0) {
case (none[ty::t[]]) { new_substs_opt = none[ty::t[]]; } case (none[vec[ty::t]]) { new_substs_opt = none[vec[ty::t]]; }
case (some[ty::t[]](?substs)) { case (some[vec[ty::t]](?substs)) {
let ty::t[] new_substs = ~[]; let vec[ty::t] new_substs = [];
for (ty::t subst in substs) { for (ty::t subst in substs) {
new_substs += ~[resolve_type_vars_in_type(fcx, sp, new_substs += [resolve_type_vars_in_type(fcx, sp, subst)];
subst)];
} }
new_substs_opt = some[ty::t[]](new_substs); new_substs_opt = some[vec[ty::t]](new_substs);
} }
} }
write::ty(fcx.ccx.tcx, id, tup(new_substs_opt, new_ty)); write::ty(fcx.ccx.tcx, id, tup(new_substs_opt, new_ty));
@ -1235,11 +1226,11 @@ fn gather_locals(&@crate_ctxt ccx, &ast::fn_decl decl, &ast::block body,
// AST fragment utilities // AST fragment utilities
fn replace_expr_type(&@fn_ctxt fcx, &@ast::expr expr, fn replace_expr_type(&@fn_ctxt fcx, &@ast::expr expr,
&tup(ty::t[], ty::t) new_tyt) { &tup(vec[ty::t], ty::t) new_tyt) {
auto new_tps; auto new_tps;
if (ty::expr_has_ty_params(fcx.ccx.tcx, expr)) { if (ty::expr_has_ty_params(fcx.ccx.tcx, expr)) {
new_tps = some[ty::t[]](new_tyt._0); new_tps = some[vec[ty::t]](new_tyt._0);
} else { new_tps = none[ty::t[]]; } } else { new_tps = none[vec[ty::t]]; }
write::ty_fixup(fcx, expr.id, tup(new_tps, new_tyt._1)); write::ty_fixup(fcx, expr.id, tup(new_tps, new_tyt._1));
} }
@ -1287,60 +1278,67 @@ fn check_pat(&@fn_ctxt fcx, &@ast::pat pat, ty::t expected) {
auto path_tpot = instantiate_path(fcx, path, tag_tpt, pat.span); auto path_tpot = instantiate_path(fcx, path, tag_tpt, pat.span);
// Take the tag type params out of `expected`. // Take the tag type params out of `expected`.
auto expected_tps;
alt (structure_of(fcx, pat.span, expected)) { alt (structure_of(fcx, pat.span, expected)) {
case (ty::ty_tag(_, ?expected_tps)) { case (ty::ty_tag(_, ?tps)) { expected_tps = tps; }
// Unify with the expected tag type. case (_) {
// FIXME: Switch expected and actual in this message? I
// can never tell.
auto ctor_ty = fcx.ccx.tcx.sess.span_fatal(pat.span,
ty::ty_param_substs_opt_and_ty_to_monotype(fcx.ccx.tcx, #fmt("mismatched types: \
path_tpot); expected tag, found %s",
ty_to_str(fcx.ccx.tcx,
expected)));
}
}
// Unify with the expected tag type.
// FIXME: Remove this ivec->vec conversion. auto ctor_ty =
auto tps_vec = ~[]; ty::ty_param_substs_opt_and_ty_to_monotype(fcx.ccx.tcx,
for (ty::t tp in expected_tps) { tps_vec += ~[tp]; } path_tpot);
auto path_tpt =
demand::full(fcx, pat.span, expected, ctor_ty, expected_tps,
NO_AUTODEREF);
path_tpot = tup(some[vec[ty::t]](path_tpt._0), path_tpt._1);
// Get the number of arguments in this tag variant.
auto path_tpt = auto arg_types =
demand::full(fcx, pat.span, expected, ctor_ty, tps_vec, variant_arg_types(fcx.ccx, pat.span, v_def_ids._1,
NO_AUTODEREF); expected_tps);
path_tpot = tup(some[ty::t[]](path_tpt._0), path_tpt._1); auto subpats_len = vec::len[@ast::pat](subpats);
// Get the number of arguments in this tag variant. if (vec::len[ty::t](arg_types) > 0u) {
// N-ary variant.
auto arg_types = auto arg_len = vec::len[ty::t](arg_types);
variant_arg_types(fcx.ccx, pat.span, v_def_ids._1, if (arg_len != subpats_len) {
expected_tps);
auto subpats_len = vec::len[@ast::pat](subpats);
if (vec::len[ty::t](arg_types) > 0u) {
// N-ary variant.
auto arg_len = vec::len[ty::t](arg_types);
if (arg_len != subpats_len) {
// TODO: note definition of tag variant
// TODO (issue #448): Wrap a #fmt string over multiple
// lines...
auto s = #fmt("this pattern has %u field%s, but the \
corresponding variant has %u field%s",
subpats_len,
if (subpats_len == 1u) {
""
} else { "s" }, arg_len,
if (arg_len == 1u) {
""
} else { "s" });
fcx.ccx.tcx.sess.span_fatal(pat.span, s);
}
// TODO: vec::iter2
auto i = 0u;
for (@ast::pat subpat in subpats) {
check_pat(fcx, subpat, arg_types.(i));
i += 1u;
}
} else if (subpats_len > 0u) {
// TODO: note definition of tag variant // TODO: note definition of tag variant
// TODO (issue #448): Wrap a #fmt string over multiple // TODO (issue #448): Wrap a #fmt string over multiple
// lines... // lines...
auto s = #fmt("this pattern has %u field%s, but the \
corresponding variant has %u field%s",
subpats_len,
if (subpats_len == 1u) {
""
} else { "s" }, arg_len,
if (arg_len == 1u) {
""
} else { "s" });
fcx.ccx.tcx.sess.span_fatal(pat.span, s);
}
// TODO: vec::iter2
fcx.ccx.tcx.sess.span_fatal(pat.span, auto i = 0u;
for (@ast::pat subpat in subpats) {
check_pat(fcx, subpat, arg_types.(i));
i += 1u;
}
} else if (subpats_len > 0u) {
// TODO: note definition of tag variant
// TODO (issue #448): Wrap a #fmt string over multiple
// lines...
fcx.ccx.tcx.sess.span_fatal(pat.span,
#fmt("this pattern has %u field%s, \ #fmt("this pattern has %u field%s, \
but the corresponding \ but the corresponding \
variant has no fields", variant has no fields",
@ -1348,19 +1346,6 @@ fn check_pat(&@fn_ctxt fcx, &@ast::pat pat, ty::t expected) {
if (subpats_len == 1u) { if (subpats_len == 1u) {
"" ""
} else { "s" })); } else { "s" }));
}
write::ty_fixup(fcx, pat.id, path_tpot);
}
case (_) {
// FIXME: Switch expected and actual in this message? I
// can never tell.
fcx.ccx.tcx.sess.span_fatal(pat.span,
#fmt("mismatched types: \
expected tag, found %s",
ty_to_str(fcx.ccx.tcx,
expected)));
}
} }
write::ty_fixup(fcx, pat.id, path_tpot); write::ty_fixup(fcx, pat.id, path_tpot);
} }
@ -1619,8 +1604,8 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
case (ty::ty_res(_, ?inner, _)) { oper_t = inner; } case (ty::ty_res(_, ?inner, _)) { oper_t = inner; }
case (ty::ty_tag(?id, ?tps)) { case (ty::ty_tag(?id, ?tps)) {
auto variants = ty::tag_variants(fcx.ccx.tcx, id); auto variants = ty::tag_variants(fcx.ccx.tcx, id);
if (ivec::len(variants) != 1u || if (vec::len(variants) != 1u ||
ivec::len(variants.(0).args) != 1u) { vec::len(variants.(0).args) != 1u) {
fcx.ccx.tcx.sess.span_fatal fcx.ccx.tcx.sess.span_fatal
(expr.span, "can only dereference tags " + (expr.span, "can only dereference tags " +
"with a single variant which has a " + "with a single variant which has a " +
@ -1664,7 +1649,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
// The definition doesn't take type parameters. If the programmer // The definition doesn't take type parameters. If the programmer
// supplied some, that's an error. // supplied some, that's an error.
if (ivec::len[@ast::ty](pth.node.types) > 0u) { if (vec::len[@ast::ty](pth.node.types) > 0u) {
fcx.ccx.tcx.sess.span_fatal(expr.span, fcx.ccx.tcx.sess.span_fatal(expr.span,
"this kind of value does not \ "this kind of value does not \
take type parameters"); take type parameters");
@ -2135,7 +2120,7 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
let uint ix = let uint ix =
ty::method_idx(fcx.ccx.tcx.sess, expr.span, field, ty::method_idx(fcx.ccx.tcx.sess, expr.span, field,
methods); methods);
if (ix >= ivec::len[ty::method](methods)) { if (ix >= vec::len[ty::method](methods)) {
fcx.ccx.tcx.sess.span_fatal(expr.span, fcx.ccx.tcx.sess.span_fatal(expr.span,
"bad index on obj"); "bad index on obj");
} }
@ -2258,32 +2243,30 @@ fn check_expr(&@fn_ctxt fcx, &@ast::expr expr) {
} }
auto output = convert(m.node.meth.decl.output); auto output = convert(m.node.meth.decl.output);
let fn(&@ast::constr) -> @ty::constr_def g =
auto out_constrs = ~[]; bind ast_constr_to_constr(ccx.tcx, _);
for (@ast::constr constr in m.node.meth.decl.constraints) { let vec[@ty::constr_def] out_constrs =
out_constrs += ~[ast_constr_to_constr(ccx.tcx, constr)]; vec::map(g, m.node.meth.decl.constraints);
}
ret rec(proto=m.node.meth.proto, ident=m.node.ident, ret rec(proto=m.node.meth.proto, ident=m.node.ident,
inputs=inputs, output=output, cf=m.node.meth.decl.cf, inputs=inputs, output=output, cf=m.node.meth.decl.cf,
constrs=out_constrs); constrs=out_constrs);
} }
fn get_anon_obj_method_types(@fn_ctxt fcx, fn get_anon_obj_method_types(@fn_ctxt fcx,
&ast::anon_obj anon_obj) &ast::anon_obj anon_obj) ->
-> ty::method[] { vec[ty::method] {
let ty::method[] methods = ~[]; let vec[ty::method] methods = [];
// Outer methods. // Outer methods.
for (@ast::method m in anon_obj.methods) { methods += vec::map[@ast::method,
methods += ~[ty_of_method(fcx.ccx, m)]; method](bind ty_of_method(fcx.ccx, _),
} anon_obj.methods);
// Inner methods. // Inner methods.
// Typecheck 'with_obj'. If it exists, it had better have // Typecheck 'with_obj'. If it exists, it had better have
// object type. // object type.
let ty::method[] with_obj_methods = ~[]; let vec[ty::method] with_obj_methods = [];
alt (anon_obj.with_obj) { alt (anon_obj.with_obj) {
case (none) { } case (none) { }
case (some(?e)) { case (some(?e)) {
@ -2357,13 +2340,7 @@ fn ast_constr_to_constr(ty::ctxt tcx, &@ast::constr c)
-> @ty::constr_def { -> @ty::constr_def {
alt (tcx.def_map.find(c.node.id)) { alt (tcx.def_map.find(c.node.id)) {
case (some(ast::def_fn(?pred_id, ast::pure_fn))) { case (some(ast::def_fn(?pred_id, ast::pure_fn))) {
// FIXME: Remove this vec->ivec conversion. ret @respan(c.span, rec(path=c.node.path, args=c.node.args,
let (@ast::constr_arg_general[uint])[] cag_ivec = ~[];
for (@ast::constr_arg_general[uint] cag in c.node.args) {
cag_ivec += ~[cag];
}
ret @respan(c.span, rec(path=c.node.path, args=cag_ivec,
id=pred_id)); id=pred_id));
} }
case (_) { case (_) {

View file

@ -1,6 +1,4 @@
// The Rust abstract syntax tree.
import std::ivec;
import std::option; import std::option;
import std::str; import std::str;
import std::vec; import std::vec;
@ -17,11 +15,11 @@ type fn_ident = option::t[ident];
// FIXME: with typestate constraint, could say // FIXME: with typestate constraint, could say
// idents and types are the same length, and are // idents and types are the same length, and are
// non-empty // non-empty
type path_ = rec(ident[] idents, (@ty)[] types); type path_ = rec(vec[ident] idents, vec[@ty] types);
type path = spanned[path_]; type path = spanned[path_];
fn path_name(&path p) -> str { ret str::connect_ivec(p.node.idents, "::"); } fn path_name(&path p) -> str { ret str::connect(p.node.idents, "::"); }
type crate_num = int; type crate_num = int;
type node_id = int; type node_id = int;
@ -81,19 +79,19 @@ fn def_id_of_def(def d) -> def_id {
// The set of meta_items that define the compilation environment of the crate, // The set of meta_items that define the compilation environment of the crate,
// used to drive conditional compilation // used to drive conditional compilation
type crate_cfg = (@meta_item)[]; type crate_cfg = vec[@meta_item];
type crate = spanned[crate_]; type crate = spanned[crate_];
type crate_ = rec((@crate_directive)[] directives, type crate_ = rec(vec[@crate_directive] directives,
_mod module, _mod module,
attribute[] attrs, vec[attribute] attrs,
crate_cfg config); crate_cfg config);
tag crate_directive_ { tag crate_directive_ {
cdir_src_mod(ident, option::t[filename], attribute[]); cdir_src_mod(ident, option::t[filename], vec[attribute]);
cdir_dir_mod(ident, option::t[filename], cdir_dir_mod(ident, option::t[filename],
(@crate_directive)[], attribute[]); vec[@crate_directive], vec[attribute]);
cdir_view_item(@view_item); cdir_view_item(@view_item);
cdir_syntax(path); cdir_syntax(path);
cdir_auth(path, _auth); cdir_auth(path, _auth);
@ -105,7 +103,7 @@ type meta_item = spanned[meta_item_];
tag meta_item_ { tag meta_item_ {
meta_word(ident); meta_word(ident);
meta_list(ident, (@meta_item)[]); meta_list(ident, vec[@meta_item]);
meta_name_value(ident, lit); meta_name_value(ident, lit);
} }
@ -505,7 +503,7 @@ type variant = spanned[variant_];
type view_item = spanned[view_item_]; type view_item = spanned[view_item_];
tag view_item_ { tag view_item_ {
view_item_use(ident, (@meta_item)[], node_id); view_item_use(ident, vec[@meta_item], node_id);
view_item_import(ident, vec[ident], node_id); view_item_import(ident, vec[ident], node_id);
view_item_import_glob(vec[ident], node_id); view_item_import_glob(vec[ident], node_id);
view_item_export(ident, node_id); view_item_export(ident, node_id);
@ -526,7 +524,7 @@ tag attr_style { attr_outer; attr_inner; }
type attribute_ = rec(attr_style style, meta_item value); type attribute_ = rec(attr_style style, meta_item value);
type item = rec(ident ident, type item = rec(ident ident,
attribute[] attrs, vec[attribute] attrs,
node_id id, // For objs and resources, this is the type def_id node_id id, // For objs and resources, this is the type def_id
item_ node, item_ node,
span span); span span);
@ -544,7 +542,7 @@ tag item_ {
} }
type native_item = rec(ident ident, type native_item = rec(ident ident,
attribute[] attrs, vec[attribute] attrs,
native_item_ node, native_item_ node,
node_id id, node_id id,
span span); span span);
@ -634,11 +632,11 @@ fn ternary_to_if(&@expr e) -> @ast::expr {
// Path stringification // Path stringification
fn path_to_str(&ast::path pth) -> str { fn path_to_str(&ast::path pth) -> str {
auto result = str::connect_ivec(pth.node.idents, "::"); auto result = str::connect(pth.node.idents, "::");
if (ivec::len[@ast::ty](pth.node.types) > 0u) { if (vec::len[@ast::ty](pth.node.types) > 0u) {
fn f(&@ast::ty t) -> str { ret print::pprust::ty_to_str(*t); } fn f(&@ast::ty t) -> str { ret print::pprust::ty_to_str(*t); }
result += "["; result += "[";
result += str::connect_ivec(ivec::map(f, pth.node.types), ","); result += str::connect(vec::map(f, pth.node.types), ",");
result += "]"; result += "]";
} }
ret result; ret result;

View file

@ -1,4 +1,3 @@
import std::ivec;
import std::vec; import std::vec;
import std::option; import std::option;
import std::map::hashmap; import std::map::hashmap;
@ -72,8 +71,8 @@ fn expr_to_str(&ext_ctxt cx, @ast::expr expr, str error) -> str {
fn expr_to_ident(&ext_ctxt cx, @ast::expr expr, str error) -> ast::ident { fn expr_to_ident(&ext_ctxt cx, @ast::expr expr, str error) -> ast::ident {
alt(expr.node) { alt(expr.node) {
case (ast::expr_path(?p)) { case (ast::expr_path(?p)) {
if (ivec::len(p.node.types) > 0u if (vec::len(p.node.types) > 0u
|| ivec::len(p.node.idents) != 1u) { || vec::len(p.node.idents) != 1u) {
cx.span_fatal(expr.span, error); cx.span_fatal(expr.span, error);
} else { } else {
ret p.node.idents.(0); ret p.node.idents.(0);

View file

@ -60,9 +60,10 @@ fn pieces_to_expr(&ext_ctxt cx, span sp, vec[piece] pieces,
auto binexpr = ast::expr_binary(ast::add, lhs, rhs); auto binexpr = ast::expr_binary(ast::add, lhs, rhs);
ret @rec(id=cx.next_id(), node=binexpr, span=sp); ret @rec(id=cx.next_id(), node=binexpr, span=sp);
} }
fn make_path_expr(&ext_ctxt cx, span sp, &ast::ident[] idents) fn make_path_expr(&ext_ctxt cx, span sp, vec[ast::ident] idents)
-> @ast::expr { -> @ast::expr {
auto path = rec(idents=idents, types=~[]); let vec[@ast::ty] types = [];
auto path = rec(idents=idents, types=types);
auto sp_path = rec(node=path, span=sp); auto sp_path = rec(node=path, span=sp);
auto pathexpr = ast::expr_path(sp_path); auto pathexpr = ast::expr_path(sp_path);
ret @rec(id=cx.next_id(), node=pathexpr, span=sp); ret @rec(id=cx.next_id(), node=pathexpr, span=sp);
@ -72,7 +73,7 @@ fn pieces_to_expr(&ext_ctxt cx, span sp, vec[piece] pieces,
auto vecexpr = ast::expr_vec(exprs, ast::imm, ast::sk_rc); auto vecexpr = ast::expr_vec(exprs, ast::imm, ast::sk_rc);
ret @rec(id=cx.next_id(), node=vecexpr, span=sp); ret @rec(id=cx.next_id(), node=vecexpr, span=sp);
} }
fn make_call(&ext_ctxt cx, span sp, &ast::ident[] fn_path, fn make_call(&ext_ctxt cx, span sp, vec[ast::ident] fn_path,
vec[@ast::expr] args) -> @ast::expr { vec[@ast::expr] args) -> @ast::expr {
auto pathexpr = make_path_expr(cx, sp, fn_path); auto pathexpr = make_path_expr(cx, sp, fn_path);
auto callexpr = ast::expr_call(pathexpr, args); auto callexpr = ast::expr_call(pathexpr, args);
@ -91,11 +92,11 @@ fn pieces_to_expr(&ext_ctxt cx, span sp, vec[piece] pieces,
auto recexpr = ast::expr_rec(astfields, option::none[@ast::expr]); auto recexpr = ast::expr_rec(astfields, option::none[@ast::expr]);
ret @rec(id=cx.next_id(), node=recexpr, span=sp); ret @rec(id=cx.next_id(), node=recexpr, span=sp);
} }
fn make_path_vec(str ident) -> str[] { fn make_path_vec(str ident) -> vec[str] {
// FIXME: #fmt can't currently be used from within std // FIXME: #fmt can't currently be used from within std
// because we're explicitly referencing the 'std' crate here // because we're explicitly referencing the 'std' crate here
ret ~["std", "extfmt", "rt", ident]; ret ["std", "extfmt", "rt", ident];
} }
fn make_rt_path_expr(&ext_ctxt cx, span sp, str ident) -> fn make_rt_path_expr(&ext_ctxt cx, span sp, str ident) ->
@ast::expr { @ast::expr {

View file

@ -1,7 +1,6 @@
use std; use std;
import codemap::span; import codemap::span;
import std::ivec;
import std::vec; import std::vec;
import std::option; import std::option;
import vec::map; import vec::map;
@ -51,7 +50,7 @@ fn subst_ident(&ext_ctxt cx, &vec[@ast::expr] args,
fn subst_path(&ext_ctxt cx, &vec[@ast::expr] args, fn subst_path(&ext_ctxt cx, &vec[@ast::expr] args,
@vec[ident] param_names, &path_ p, ast_fold fld) -> path_ { @vec[ident] param_names, &path_ p, ast_fold fld) -> path_ {
// Don't substitute into qualified names. // Don't substitute into qualified names.
if (ivec::len(p.types) > 0u || ivec::len(p.idents) != 1u) { ret p; } if (len(p.types) > 0u || len(p.idents) != 1u) { ret p; }
alt (position(p.idents.(0), *param_names)) { alt (position(p.idents.(0), *param_names)) {
case (some[uint](?idx)) { case (some[uint](?idx)) {
alt (args.(idx).node) { alt (args.(idx).node) {
@ -76,8 +75,7 @@ fn subst_expr(&ext_ctxt cx, &vec[@ast::expr] args, @vec[ident] param_names,
ret alt(e) { ret alt(e) {
case (expr_path(?p)){ case (expr_path(?p)){
// Don't substitute into qualified names. // Don't substitute into qualified names.
if (ivec::len(p.node.types) > 0u || if (len(p.node.types) > 0u || len(p.node.idents) != 1u) { e }
ivec::len(p.node.idents) != 1u) { e }
alt (position(p.node.idents.(0), *param_names)) { alt (position(p.node.idents.(0), *param_names)) {
case (some[uint](?idx)) { case (some[uint](?idx)) {
args.(idx).node args.(idx).node

View file

@ -1,7 +1,6 @@
import syntax::codemap::span; import syntax::codemap::span;
import ast::*; import ast::*;
import std::ivec;
import std::vec; import std::vec;
import std::option; import std::option;
import vec::map; import vec::map;
@ -103,7 +102,7 @@ fn fold_meta_item_(&@meta_item mi, ast_fold fld) -> @meta_item {
case (meta_word(?id)) { meta_word(fld.fold_ident(id)) } case (meta_word(?id)) { meta_word(fld.fold_ident(id)) }
case (meta_list(?id, ?mis)) { case (meta_list(?id, ?mis)) {
auto fold_meta_item = bind fold_meta_item_(_,fld); auto fold_meta_item = bind fold_meta_item_(_,fld);
meta_list(id, ivec::map(fold_meta_item, mis)) meta_list(id, map(fold_meta_item, mis))
} }
case (meta_name_value(?id,?s)) { case (meta_name_value(?id,?s)) {
meta_name_value(fld.fold_ident(id),s) meta_name_value(fld.fold_ident(id),s)
@ -131,10 +130,10 @@ fn noop_fold_crate(&crate_ c, ast_fold fld) -> crate_ {
auto fold_meta_item = bind fold_meta_item_(_,fld); auto fold_meta_item = bind fold_meta_item_(_,fld);
auto fold_attribute = bind fold_attribute_(_,fold_meta_item); auto fold_attribute = bind fold_attribute_(_,fold_meta_item);
ret rec(directives=ivec::map(fld.fold_crate_directive, c.directives), ret rec(directives=map(fld.fold_crate_directive, c.directives),
module=fld.fold_mod(c.module), module=fld.fold_mod(c.module),
attrs=ivec::map(fold_attribute, c.attrs), attrs=map(fold_attribute, c.attrs),
config=ivec::map(fold_meta_item, c.config)); config=map(fold_meta_item, c.config));
} }
fn noop_fold_crate_directive(&crate_directive_ cd, ast_fold fld) fn noop_fold_crate_directive(&crate_directive_ cd, ast_fold fld)
@ -145,7 +144,7 @@ fn noop_fold_crate_directive(&crate_directive_ cd, ast_fold fld)
} }
case(cdir_dir_mod(?id,?fname,?cds,?attrs)) { case(cdir_dir_mod(?id,?fname,?cds,?attrs)) {
cdir_dir_mod(fld.fold_ident(id),fname, cdir_dir_mod(fld.fold_ident(id),fname,
ivec::map(fld.fold_crate_directive, cds), attrs) map(fld.fold_crate_directive, cds), attrs)
} }
case(cdir_view_item(?vi)) { case(cdir_view_item(?vi)) {
cdir_view_item(fld.fold_view_item(vi)) cdir_view_item(fld.fold_view_item(vi))
@ -166,7 +165,7 @@ fn noop_fold_native_item(&@native_item ni, ast_fold fld) -> @native_item {
auto fold_attribute = bind fold_attribute_(_,fold_meta_item); auto fold_attribute = bind fold_attribute_(_,fold_meta_item);
ret @rec(ident=fld.fold_ident(ni.ident), ret @rec(ident=fld.fold_ident(ni.ident),
attrs=ivec::map(fold_attribute, ni.attrs), attrs=map(fold_attribute, ni.attrs),
node=alt (ni.node) { node=alt (ni.node) {
case (native_item_ty) { native_item_ty } case (native_item_ty) { native_item_ty }
case (native_item_fn(?st, ?fdec, ?typms)) { case (native_item_fn(?st, ?fdec, ?typms)) {
@ -188,7 +187,7 @@ fn noop_fold_item(&@item i, ast_fold fld) -> @item {
auto fold_attribute = bind fold_attribute_(_,fold_meta_item); auto fold_attribute = bind fold_attribute_(_,fold_meta_item);
ret @rec(ident=fld.fold_ident(i.ident), ret @rec(ident=fld.fold_ident(i.ident),
attrs=ivec::map(fold_attribute,i.attrs), attrs=map(fold_attribute,i.attrs),
id=i.id, node=fld.fold_item_underscore(i.node), id=i.id, node=fld.fold_item_underscore(i.node),
span=i.span); span=i.span);
} }
@ -486,8 +485,8 @@ fn noop_fold_ident(&ident i, ast_fold fld) -> ident {
} }
fn noop_fold_path(&path_ p, ast_fold fld) -> path_ { fn noop_fold_path(&path_ p, ast_fold fld) -> path_ {
ret rec(idents=ivec::map(fld.fold_ident, p.idents), ret rec(idents=map(fld.fold_ident, p.idents),
types=ivec::map(fld.fold_ty, p.types)); types=map(fld.fold_ty, p.types));
} }
fn noop_fold_local(&local_ l, ast_fold fld) -> local_ { fn noop_fold_local(&local_ l, ast_fold fld) -> local_ {

View file

@ -24,7 +24,7 @@ type ctx =
mutable uint chpos, mutable uint chpos,
ast::crate_cfg cfg); ast::crate_cfg cfg);
fn eval_crate_directives(ctx cx, &(@ast::crate_directive)[] cdirs, fn eval_crate_directives(ctx cx, vec[@ast::crate_directive] cdirs,
str prefix, &mutable vec[@ast::view_item] view_items, str prefix, &mutable vec[@ast::view_item] view_items,
&mutable vec[@ast::item] items) { &mutable vec[@ast::item] items) {
for (@ast::crate_directive sub_cdir in cdirs) { for (@ast::crate_directive sub_cdir in cdirs) {
@ -32,8 +32,9 @@ fn eval_crate_directives(ctx cx, &(@ast::crate_directive)[] cdirs,
} }
} }
fn eval_crate_directives_to_mod(ctx cx, &(@ast::crate_directive)[] cdirs, fn eval_crate_directives_to_mod(ctx cx,
str prefix) -> ast::_mod { vec[@ast::crate_directive] cdirs, str prefix)
-> ast::_mod {
let vec[@ast::view_item] view_items = []; let vec[@ast::view_item] view_items = [];
let vec[@ast::item] items = []; let vec[@ast::item] items = [];
eval_crate_directives(cx, cdirs, prefix, view_items, items); eval_crate_directives(cx, cdirs, prefix, view_items, items);

View file

@ -1,6 +1,5 @@
import std::io; import std::io;
import std::ivec;
import std::vec; import std::vec;
import std::str; import std::str;
import std::option; import std::option;
@ -410,18 +409,13 @@ fn parse_ty_postfix(@ast::ty orig_t, &parser p) -> @ast::ty {
// This is explicit type parameter instantiation. // This is explicit type parameter instantiation.
auto seq = parse_seq_to_end(token::RBRACKET, some(token::COMMA), auto seq = parse_seq_to_end(token::RBRACKET, some(token::COMMA),
parse_ty, p); parse_ty, p);
// FIXME: Remove this vec->ivec conversion.
auto seq_ivec = ~[];
for (@ast::ty typ in seq) { seq_ivec += ~[typ]; }
alt (orig_t.node) { alt (orig_t.node) {
case (ast::ty_path(?pth, ?ann)) { case (ast::ty_path(?pth, ?ann)) {
auto hi = p.get_hi_pos(); auto hi = p.get_hi_pos();
ret @spanned(lo, hi, ret @spanned(lo, hi,
ast::ty_path(spanned(lo, hi, ast::ty_path(spanned(lo, hi,
rec(idents=pth.node.idents, rec(idents=pth.node.idents,
types=seq_ivec)), types=seq)),
ann)); ann));
} }
case (_) { case (_) {
@ -591,24 +585,6 @@ fn parse_seq_to_end[T](token::token ket, option::t[token::token] sep,
ret v; ret v;
} }
fn parse_seq_to_end_ivec[T](token::token ket, option::t[token::token] sep,
fn(&parser)->T f, &parser p) -> T[] {
let bool first = true;
let T[] v = ~[];
while (p.peek() != ket) {
alt (sep) {
case (some(?t)) {
if (first) { first = false; } else { expect(p, t); }
}
case (_) { }
}
v += ~[f(p)];
}
expect(p, ket);
ret v;
}
fn parse_seq[T](token::token bra, token::token ket, fn parse_seq[T](token::token bra, token::token ket,
option::t[token::token] sep, fn(&parser) -> T f, &parser p) option::t[token::token] sep, fn(&parser) -> T f, &parser p)
-> ast::spanned[vec[T]] { -> ast::spanned[vec[T]] {
@ -619,17 +595,6 @@ fn parse_seq[T](token::token bra, token::token ket,
ret spanned(lo, hi, result); ret spanned(lo, hi, result);
} }
fn parse_seq_ivec[T](token::token bra, token::token ket,
option::t[token::token] sep,
fn(&parser)->T f, &parser p) -> ast::spanned[T[]] {
auto lo = p.get_lo_pos();
expect(p, bra);
auto result = parse_seq_to_end_ivec[T](ket, sep, f, p);
auto hi = p.get_hi_pos();
ret spanned(lo, hi, result);
}
fn parse_lit(&parser p) -> ast::lit { fn parse_lit(&parser p) -> ast::lit {
auto sp = p.get_span(); auto sp = p.get_span();
let ast::lit_ lit = ast::lit_nil; let ast::lit_ lit = ast::lit_nil;
@ -672,12 +637,12 @@ fn is_ident(token::token t) -> bool {
fn parse_path(&parser p) -> ast::path { fn parse_path(&parser p) -> ast::path {
auto lo = p.get_lo_pos(); auto lo = p.get_lo_pos();
auto hi = lo; auto hi = lo;
let ast::ident[] ids = ~[]; let vec[ast::ident] ids = [];
while (true) { while (true) {
alt (p.peek()) { alt (p.peek()) {
case (token::IDENT(?i, _)) { case (token::IDENT(?i, _)) {
hi = p.get_hi_pos(); hi = p.get_hi_pos();
ids += ~[p.get_str(i)]; ids += [p.get_str(i)];
p.bump(); p.bump();
if (p.peek() == token::MOD_SEP) { p.bump(); } else { break; } if (p.peek() == token::MOD_SEP) { p.bump(); } else { break; }
} }
@ -685,7 +650,7 @@ fn parse_path(&parser p) -> ast::path {
} }
} }
hi = p.get_hi_pos(); hi = p.get_hi_pos();
ret spanned(lo, hi, rec(idents=ids, types=~[])); ret spanned(lo, hi, rec(idents=ids, types=[]));
} }
fn parse_path_and_ty_param_substs(&parser p) -> ast::path { fn parse_path_and_ty_param_substs(&parser p) -> ast::path {
@ -694,13 +659,8 @@ fn parse_path_and_ty_param_substs(&parser p) -> ast::path {
if (p.peek() == token::LBRACKET) { if (p.peek() == token::LBRACKET) {
auto seq = parse_seq(token::LBRACKET, token::RBRACKET, auto seq = parse_seq(token::LBRACKET, token::RBRACKET,
some(token::COMMA), parse_ty, p); some(token::COMMA), parse_ty, p);
// FIXME: Remove this vec->ivec conversion.
auto seq_ivec = ~[];
for (@ast::ty typ in seq.node) { seq_ivec += ~[typ]; }
auto hi = p.get_hi_pos(); auto hi = p.get_hi_pos();
path = spanned(lo, hi, rec(idents=path.node.idents, types=seq_ivec)); path = spanned(lo, hi, rec(idents=path.node.idents, types=seq.node));
} }
ret path; ret path;
} }
@ -995,7 +955,7 @@ fn parse_syntax_ext(&parser p) -> @ast::expr {
fn parse_syntax_ext_naked(&parser p, uint lo) -> @ast::expr { fn parse_syntax_ext_naked(&parser p, uint lo) -> @ast::expr {
auto pth = parse_path(p); auto pth = parse_path(p);
if (ivec::len(pth.node.idents) == 0u) { if (vec::len(pth.node.idents) == 0u) {
p.fatal("expected a syntax expander name"); p.fatal("expected a syntax expander name");
} }
auto es = parse_seq(token::LPAREN, token::RPAREN, auto es = parse_seq(token::LPAREN, token::RPAREN,
@ -1015,7 +975,7 @@ fn parse_syntax_ext_naked(&parser p, uint lo) -> @ast::expr {
fn expand_syntax_ext(&parser p, span sp, &ast::path path, fn expand_syntax_ext(&parser p, span sp, &ast::path path,
vec[@ast::expr] args, option::t[str] body) -> vec[@ast::expr] args, option::t[str] body) ->
ast::expr_ { ast::expr_ {
assert (ivec::len(path.node.idents) > 0u); assert (vec::len(path.node.idents) > 0u);
auto extname = path.node.idents.(0); auto extname = path.node.idents.(0);
alt (p.get_syntax_expanders().find(extname)) { alt (p.get_syntax_expanders().find(extname)) {
case (none) { p.fatal("unknown syntax expander: '" + extname + "'"); } case (none) { p.fatal("unknown syntax expander: '" + extname + "'"); }
@ -1509,7 +1469,7 @@ fn parse_stmt(&parser p) -> @ast::stmt {
} }
fn parse_crate_stmt(&parser p) -> @ast::stmt { fn parse_crate_stmt(&parser p) -> @ast::stmt {
auto cdir = parse_crate_directive(p, ~[]); auto cdir = parse_crate_directive(p, []);
ret @spanned(cdir.span.lo, cdir.span.hi, ret @spanned(cdir.span.lo, cdir.span.hi,
ast::stmt_crate_directive(@cdir)); ast::stmt_crate_directive(@cdir));
} }
@ -1527,7 +1487,7 @@ fn parse_source_stmt(&parser p) -> @ast::stmt {
auto item_attrs; auto item_attrs;
alt (parse_outer_attrs_or_ext(p)) { alt (parse_outer_attrs_or_ext(p)) {
case (none) { case (none) {
item_attrs = ~[]; item_attrs = [];
} }
case (some(left(?attrs))) { case (some(left(?attrs))) {
item_attrs = attrs; item_attrs = attrs;
@ -1541,7 +1501,7 @@ fn parse_source_stmt(&parser p) -> @ast::stmt {
auto maybe_item = parse_item(p, item_attrs); auto maybe_item = parse_item(p, item_attrs);
// If we have attributes then we should have an item // If we have attributes then we should have an item
if (ivec::len(item_attrs) > 0u) { if (vec::len(item_attrs) > 0u) {
alt (maybe_item) { alt (maybe_item) {
case (got_item(_)) { /* fallthrough */ } case (got_item(_)) { /* fallthrough */ }
case (_) { case (_) {
@ -1747,7 +1707,7 @@ fn parse_fn_header(&parser p) -> tup(ast::ident, vec[ast::ty_param]) {
} }
fn mk_item(&parser p, uint lo, uint hi, &ast::ident ident, &ast::item_ node, fn mk_item(&parser p, uint lo, uint hi, &ast::ident ident, &ast::item_ node,
&ast::attribute[] attrs) -> @ast::item { &vec[ast::attribute] attrs) -> @ast::item {
ret @rec(ident=ident, ret @rec(ident=ident,
attrs=attrs, attrs=attrs,
id=p.get_id(), id=p.get_id(),
@ -1756,7 +1716,7 @@ fn mk_item(&parser p, uint lo, uint hi, &ast::ident ident, &ast::item_ node,
} }
fn parse_item_fn_or_iter(&parser p, ast::purity purity, ast::proto proto, fn parse_item_fn_or_iter(&parser p, ast::purity purity, ast::proto proto,
&ast::attribute[] attrs) -> @ast::item { vec[ast::attribute] attrs) -> @ast::item {
auto lo = p.get_last_lo_pos(); auto lo = p.get_last_lo_pos();
auto t = parse_fn_header(p); auto t = parse_fn_header(p);
auto f = parse_fn(p, proto, purity); auto f = parse_fn(p, proto, purity);
@ -1807,7 +1767,7 @@ fn parse_dtor(&parser p) -> @ast::method {
ret @spanned(lo, f.body.span.hi, m); ret @spanned(lo, f.body.span.hi, m);
} }
fn parse_item_obj(&parser p, ast::layer lyr, &ast::attribute[] attrs) -> fn parse_item_obj(&parser p, ast::layer lyr, vec[ast::attribute] attrs) ->
@ast::item { @ast::item {
auto lo = p.get_last_lo_pos(); auto lo = p.get_last_lo_pos();
auto ident = parse_value_ident(p); auto ident = parse_value_ident(p);
@ -1830,7 +1790,7 @@ fn parse_item_obj(&parser p, ast::layer lyr, &ast::attribute[] attrs) ->
p.get_id()), attrs); p.get_id()), attrs);
} }
fn parse_item_res(&parser p, ast::layer lyr, &ast::attribute[] attrs) -> fn parse_item_res(&parser p, ast::layer lyr, vec[ast::attribute] attrs) ->
@ast::item { @ast::item {
auto lo = p.get_last_lo_pos(); auto lo = p.get_last_lo_pos();
auto ident = parse_value_ident(p); auto ident = parse_value_ident(p);
@ -1852,8 +1812,8 @@ fn parse_item_res(&parser p, ast::layer lyr, &ast::attribute[] attrs) ->
} }
fn parse_mod_items(&parser p, token::token term, fn parse_mod_items(&parser p, token::token term,
&ast::attribute[] first_item_attrs) -> ast::_mod { vec[ast::attribute] first_item_attrs) -> ast::_mod {
auto view_items = if (ivec::len(first_item_attrs) == 0u) { auto view_items = if (vec::len(first_item_attrs) == 0u) {
parse_view(p) parse_view(p)
} else { } else {
// Shouldn't be any view items since we've already parsed an item attr // Shouldn't be any view items since we've already parsed an item attr
@ -1863,7 +1823,7 @@ fn parse_mod_items(&parser p, token::token term,
auto initial_attrs = first_item_attrs; auto initial_attrs = first_item_attrs;
while (p.peek() != term) { while (p.peek() != term) {
auto attrs = initial_attrs + parse_outer_attributes(p); auto attrs = initial_attrs + parse_outer_attributes(p);
initial_attrs = ~[]; initial_attrs = [];
alt (parse_item(p, attrs)) { alt (parse_item(p, attrs)) {
case (got_item(?i)) { vec::push(items, i); } case (got_item(?i)) { vec::push(items, i); }
case (_) { case (_) {
@ -1875,7 +1835,7 @@ fn parse_mod_items(&parser p, token::token term,
ret rec(view_items=view_items, items=items); ret rec(view_items=view_items, items=items);
} }
fn parse_item_const(&parser p, &ast::attribute[] attrs) -> @ast::item { fn parse_item_const(&parser p, vec[ast::attribute] attrs) -> @ast::item {
auto lo = p.get_last_lo_pos(); auto lo = p.get_last_lo_pos();
auto ty = parse_ty(p); auto ty = parse_ty(p);
auto id = parse_value_ident(p); auto id = parse_value_ident(p);
@ -1886,20 +1846,21 @@ fn parse_item_const(&parser p, &ast::attribute[] attrs) -> @ast::item {
ret mk_item(p, lo, hi, id, ast::item_const(ty, e), attrs); ret mk_item(p, lo, hi, id, ast::item_const(ty, e), attrs);
} }
fn parse_item_mod(&parser p, &ast::attribute[] attrs) -> @ast::item { fn parse_item_mod(&parser p, vec[ast::attribute] attrs) -> @ast::item {
auto lo = p.get_last_lo_pos(); auto lo = p.get_last_lo_pos();
auto id = parse_ident(p); auto id = parse_ident(p);
expect(p, token::LBRACE); expect(p, token::LBRACE);
auto inner_attrs = parse_inner_attrs_and_next(p); auto inner_attrs = parse_inner_attrs_and_next(p);
auto first_item_outer_attrs = inner_attrs._1; auto first_item_outer_attrs = inner_attrs._1;
auto m = parse_mod_items(p, token::RBRACE, first_item_outer_attrs); auto m = parse_mod_items(p, token::RBRACE,
first_item_outer_attrs);
auto hi = p.get_hi_pos(); auto hi = p.get_hi_pos();
expect(p, token::RBRACE); expect(p, token::RBRACE);
ret mk_item(p, lo, hi, id, ast::item_mod(m), attrs + inner_attrs._0); ret mk_item(p, lo, hi, id, ast::item_mod(m), attrs + inner_attrs._0);
} }
fn parse_item_native_type(&parser p, &ast::attribute[] attrs) fn parse_item_native_type(&parser p,
-> @ast::native_item { &vec[ast::attribute] attrs) -> @ast::native_item {
auto t = parse_type_decl(p); auto t = parse_type_decl(p);
auto hi = p.get_hi_pos(); auto hi = p.get_hi_pos();
expect(p, token::SEMI); expect(p, token::SEMI);
@ -1910,8 +1871,8 @@ fn parse_item_native_type(&parser p, &ast::attribute[] attrs)
span=rec(lo=t._0, hi=hi)); span=rec(lo=t._0, hi=hi));
} }
fn parse_item_native_fn(&parser p, &ast::attribute[] attrs) fn parse_item_native_fn(&parser p,
-> @ast::native_item { &vec[ast::attribute] attrs) -> @ast::native_item {
auto lo = p.get_last_lo_pos(); auto lo = p.get_last_lo_pos();
auto t = parse_fn_header(p); auto t = parse_fn_header(p);
auto decl = parse_fn_decl(p, ast::impure_fn); auto decl = parse_fn_decl(p, ast::impure_fn);
@ -1929,8 +1890,8 @@ fn parse_item_native_fn(&parser p, &ast::attribute[] attrs)
span=rec(lo=lo, hi=hi)); span=rec(lo=lo, hi=hi));
} }
fn parse_native_item(&parser p, &ast::attribute[] attrs) fn parse_native_item(&parser p,
-> @ast::native_item { &vec[ast::attribute] attrs) -> @ast::native_item {
parse_layer(p); parse_layer(p);
if (eat_word(p, "type")) { if (eat_word(p, "type")) {
ret parse_item_native_type(p, attrs); ret parse_item_native_type(p, attrs);
@ -1940,9 +1901,9 @@ fn parse_native_item(&parser p, &ast::attribute[] attrs)
} }
fn parse_native_mod_items(&parser p, &str native_name, ast::native_abi abi, fn parse_native_mod_items(&parser p, &str native_name, ast::native_abi abi,
&ast::attribute[] first_item_attrs) &vec[ast::attribute] first_item_attrs) ->
-> ast::native_mod { ast::native_mod {
auto view_items = if (ivec::len(first_item_attrs) == 0u) { auto view_items = if (vec::len(first_item_attrs) == 0u) {
parse_native_view(p) parse_native_view(p)
} else { } else {
// Shouldn't be any view items since we've already parsed an item attr // Shouldn't be any view items since we've already parsed an item attr
@ -1952,7 +1913,7 @@ fn parse_native_mod_items(&parser p, &str native_name, ast::native_abi abi,
auto initial_attrs = first_item_attrs; auto initial_attrs = first_item_attrs;
while (p.peek() != token::RBRACE) { while (p.peek() != token::RBRACE) {
auto attrs = initial_attrs + parse_outer_attributes(p); auto attrs = initial_attrs + parse_outer_attributes(p);
initial_attrs = ~[]; initial_attrs = [];
items += [parse_native_item(p, attrs)]; items += [parse_native_item(p, attrs)];
} }
ret rec(native_name=native_name, ret rec(native_name=native_name,
@ -1961,7 +1922,7 @@ fn parse_native_mod_items(&parser p, &str native_name, ast::native_abi abi,
items=items); items=items);
} }
fn parse_item_native_mod(&parser p, &ast::attribute[] attrs) -> @ast::item { fn parse_item_native_mod(&parser p, vec[ast::attribute] attrs) -> @ast::item {
auto lo = p.get_last_lo_pos(); auto lo = p.get_last_lo_pos();
auto abi = ast::native_abi_cdecl; auto abi = ast::native_abi_cdecl;
if (!is_word(p, "mod")) { if (!is_word(p, "mod")) {
@ -2001,7 +1962,7 @@ fn parse_type_decl(&parser p) -> tup(uint, ast::ident) {
ret tup(lo, id); ret tup(lo, id);
} }
fn parse_item_type(&parser p, &ast::attribute[] attrs) -> @ast::item { fn parse_item_type(&parser p, vec[ast::attribute] attrs) -> @ast::item {
auto t = parse_type_decl(p); auto t = parse_type_decl(p);
auto tps = parse_ty_params(p); auto tps = parse_ty_params(p);
expect(p, token::EQ); expect(p, token::EQ);
@ -2011,7 +1972,7 @@ fn parse_item_type(&parser p, &ast::attribute[] attrs) -> @ast::item {
ret mk_item(p, t._0, hi, t._1, ast::item_ty(ty, tps), attrs); ret mk_item(p, t._0, hi, t._1, ast::item_ty(ty, tps), attrs);
} }
fn parse_item_tag(&parser p, &ast::attribute[] attrs) -> @ast::item { fn parse_item_tag(&parser p, vec[ast::attribute] attrs) -> @ast::item {
auto lo = p.get_last_lo_pos(); auto lo = p.get_last_lo_pos();
auto id = parse_ident(p); auto id = parse_ident(p);
auto ty_params = parse_ty_params(p); auto ty_params = parse_ty_params(p);
@ -2090,7 +2051,7 @@ fn parse_auth(&parser p) -> ast::_auth {
tag parsed_item { got_item(@ast::item); no_item; fn_no_item; } tag parsed_item { got_item(@ast::item); no_item; fn_no_item; }
fn parse_item(&parser p, &ast::attribute[] attrs) -> parsed_item { fn parse_item(&parser p, vec[ast::attribute] attrs) -> parsed_item {
if (eat_word(p, "const")) { if (eat_word(p, "const")) {
ret got_item(parse_item_const(p, attrs)); ret got_item(parse_item_const(p, attrs));
} else if (eat_word(p, "fn")) { } else if (eat_word(p, "fn")) {
@ -2124,7 +2085,8 @@ fn parse_item(&parser p, &ast::attribute[] attrs) -> parsed_item {
// A type to distingush between the parsing of item attributes or syntax // A type to distingush between the parsing of item attributes or syntax
// extensions, which both begin with token.POUND // extensions, which both begin with token.POUND
type attr_or_ext = option::t[either::t[ast::attribute[], @ast::expr]]; type attr_or_ext = option::t[either::t[vec[ast::attribute],
@ast::expr]];
fn parse_outer_attrs_or_ext(&parser p) -> attr_or_ext { fn parse_outer_attrs_or_ext(&parser p) -> attr_or_ext {
if (p.peek() == token::POUND) { if (p.peek() == token::POUND) {
@ -2132,7 +2094,7 @@ fn parse_outer_attrs_or_ext(&parser p) -> attr_or_ext {
p.bump(); p.bump();
if (p.peek() == token::LBRACKET) { if (p.peek() == token::LBRACKET) {
auto first_attr = parse_attribute_naked(p, ast::attr_outer, lo); auto first_attr = parse_attribute_naked(p, ast::attr_outer, lo);
ret some(left(~[first_attr] + parse_outer_attributes(p))); ret some(left([first_attr] + parse_outer_attributes(p)));
} else { } else {
ret some(right(parse_syntax_ext_naked(p, lo))); ret some(right(parse_syntax_ext_naked(p, lo)));
} }
@ -2142,10 +2104,10 @@ fn parse_outer_attrs_or_ext(&parser p) -> attr_or_ext {
} }
// Parse attributes that appear before an item // Parse attributes that appear before an item
fn parse_outer_attributes(&parser p) -> ast::attribute[] { fn parse_outer_attributes(&parser p) -> vec[ast::attribute] {
let ast::attribute[] attrs = ~[]; let vec[ast::attribute] attrs = [];
while (p.peek() == token::POUND) { while (p.peek() == token::POUND) {
attrs += ~[parse_attribute(p, ast::attr_outer)]; attrs += [parse_attribute(p, ast::attr_outer)];
} }
ret attrs; ret attrs;
} }
@ -2171,22 +2133,22 @@ fn parse_attribute_naked(&parser p, ast::attr_style style,
// next item (since we can't know whether the attribute is an inner attribute // next item (since we can't know whether the attribute is an inner attribute
// of the containing item or an outer attribute of the first contained item // of the containing item or an outer attribute of the first contained item
// until we see the semi). // until we see the semi).
fn parse_inner_attrs_and_next(&parser p) -> tup(ast::attribute[], fn parse_inner_attrs_and_next(&parser p) -> tup(vec[ast::attribute],
ast::attribute[]) { vec[ast::attribute]) {
let ast::attribute[] inner_attrs = ~[]; let vec[ast::attribute] inner_attrs = [];
let ast::attribute[] next_outer_attrs = ~[]; let vec[ast::attribute] next_outer_attrs = [];
while (p.peek() == token::POUND) { while (p.peek() == token::POUND) {
auto attr = parse_attribute(p, ast::attr_inner); auto attr = parse_attribute(p, ast::attr_inner);
if (p.peek() == token::SEMI) { if (p.peek() == token::SEMI) {
p.bump(); p.bump();
inner_attrs += ~[attr]; inner_attrs += [attr];
} else { } else {
// It's not really an inner attribute // It's not really an inner attribute
auto outer_attr = spanned(attr.span.lo, auto outer_attr = spanned(attr.span.lo,
attr.span.hi, attr.span.hi,
rec(style=ast::attr_outer, rec(style=ast::attr_outer,
value=attr.node.value)); value=attr.node.value));
next_outer_attrs += ~[outer_attr]; next_outer_attrs += [outer_attr];
break; break;
} }
} }
@ -2215,15 +2177,15 @@ fn parse_meta_item(&parser p) -> @ast::meta_item {
} }
} }
fn parse_meta_seq(&parser p) -> (@ast::meta_item)[] { fn parse_meta_seq(&parser p) -> vec[@ast::meta_item] {
ret parse_seq_ivec(token::LPAREN, token::RPAREN, some(token::COMMA), ret parse_seq(token::LPAREN, token::RPAREN, some(token::COMMA),
parse_meta_item, p).node; parse_meta_item, p).node;
} }
fn parse_optional_meta(&parser p) -> (@ast::meta_item)[] { fn parse_optional_meta(&parser p) -> vec[@ast::meta_item] {
alt (p.peek()) { alt (p.peek()) {
case (token::LPAREN) { ret parse_meta_seq(p); } case (token::LPAREN) { ret parse_meta_seq(p); }
case (_) { ret ~[]; } case (_) { let vec[@ast::meta_item] v = []; ret v; }
} }
} }
@ -2233,7 +2195,8 @@ fn parse_use(&parser p) -> @ast::view_item {
auto metadata = parse_optional_meta(p); auto metadata = parse_optional_meta(p);
auto hi = p.get_hi_pos(); auto hi = p.get_hi_pos();
expect(p, token::SEMI); expect(p, token::SEMI);
auto use_decl = ast::view_item_use(ident, metadata, p.get_id()); auto use_decl =
ast::view_item_use(ident, metadata, p.get_id());
ret @spanned(lo, hi, use_decl); ret @spanned(lo, hi, use_decl);
} }
@ -2366,7 +2329,8 @@ fn parse_crate_from_source_file(&str input, &ast::crate_cfg cfg,
auto first_item_outer_attrs = crate_attrs._1; auto first_item_outer_attrs = crate_attrs._1;
auto m = parse_mod_items(p, token::EOF, auto m = parse_mod_items(p, token::EOF,
first_item_outer_attrs); first_item_outer_attrs);
ret @spanned(lo, p.get_lo_pos(), rec(directives=~[], let vec[@ast::crate_directive] cdirs = [];
ret @spanned(lo, p.get_lo_pos(), rec(directives=cdirs,
module=m, module=m,
attrs=crate_attrs._0, attrs=crate_attrs._0,
config=p.get_cfg())); config=p.get_cfg()));
@ -2387,13 +2351,14 @@ fn parse_str(&parser p) -> ast::ident {
// Each crate file is a sequence of directives. // Each crate file is a sequence of directives.
// //
// Each directive imperatively extends its environment with 0 or more items. // Each directive imperatively extends its environment with 0 or more items.
fn parse_crate_directive(&parser p, &ast::attribute[] first_outer_attr) fn parse_crate_directive(&parser p, vec[ast::attribute] first_outer_attr)
-> ast::crate_directive { -> ast::crate_directive {
// Collect the next attributes // Collect the next attributes
auto outer_attrs = first_outer_attr + parse_outer_attributes(p); auto outer_attrs = first_outer_attr
+ parse_outer_attributes(p);
// In a crate file outer attributes are only going to apply to mods // In a crate file outer attributes are only going to apply to mods
auto expect_mod = ivec::len(outer_attrs) > 0u; auto expect_mod = vec::len(outer_attrs) > 0u;
auto lo = p.get_lo_pos(); auto lo = p.get_lo_pos();
if (expect_mod || is_word(p, "mod")) { if (expect_mod || is_word(p, "mod")) {
@ -2448,20 +2413,20 @@ fn parse_crate_directive(&parser p, &ast::attribute[] first_outer_attr)
} }
fn parse_crate_directives(&parser p, token::token term, fn parse_crate_directives(&parser p, token::token term,
&ast::attribute[] first_outer_attr) vec[ast::attribute] first_outer_attr) ->
-> (@ast::crate_directive)[] { vec[@ast::crate_directive] {
// This is pretty ugly. If we have an outer attribute then we can't accept // This is pretty ugly. If we have an outer attribute then we can't accept
// seeing the terminator next, so if we do see it then fail the same way // seeing the terminator next, so if we do see it then fail the same way
// parse_crate_directive would // parse_crate_directive would
if (ivec::len(first_outer_attr) > 0u && p.peek() == term) { if (vec::len(first_outer_attr) > 0u && p.peek() == term) {
expect_word(p, "mod"); expect_word(p, "mod");
} }
let (@ast::crate_directive)[] cdirs = ~[]; let vec[@ast::crate_directive] cdirs = [];
while (p.peek() != term) { while (p.peek() != term) {
auto cdir = @parse_crate_directive(p, first_outer_attr); auto cdir = @parse_crate_directive(p, first_outer_attr);
cdirs += ~[cdir]; vec::push(cdirs, cdir);
} }
ret cdirs; ret cdirs;
} }

View file

@ -1,10 +1,9 @@
import std::ivec;
import std::int;
import std::io;
import std::str;
import std::uint; import std::uint;
import std::int;
import std::vec; import std::vec;
import std::str;
import std::io;
import std::option; import std::option;
import parse::lexer; import parse::lexer;
import syntax::codemap::codemap; import syntax::codemap::codemap;
@ -207,17 +206,6 @@ fn commasep[IN](&ps s, breaks b, vec[IN] elts, fn(&ps, &IN) op) {
end(s); end(s);
} }
fn commasep_ivec[IN](&ps s, breaks b, &IN[] elts, fn(&ps, &IN) op) {
box(s, 0u, b);
auto first = true;
for (IN elt in elts) {
if (first) { first = false; } else { word_space(s, ","); }
op(s, elt);
}
end(s);
}
fn commasep_cmnt[IN](&ps s, breaks b, vec[IN] elts, fn(&ps, &IN) op, fn commasep_cmnt[IN](&ps s, breaks b, vec[IN] elts, fn(&ps, &IN) op,
fn(&IN) -> codemap::span get_span) { fn(&IN) -> codemap::span get_span) {
box(s, 0u, b); box(s, 0u, b);
@ -242,7 +230,7 @@ fn commasep_exprs(&ps s, breaks b, vec[@ast::expr] exprs) {
commasep_cmnt(s, b, exprs, print_expr, expr_span); commasep_cmnt(s, b, exprs, print_expr, expr_span);
} }
fn print_mod(&ps s, ast::_mod _mod, &ast::attribute[] attrs) { fn print_mod(&ps s, ast::_mod _mod, &vec[ast::attribute] attrs) {
print_inner_attributes(s, attrs); print_inner_attributes(s, attrs);
for (@ast::view_item vitem in _mod.view_items) { for (@ast::view_item vitem in _mod.view_items) {
print_view_item(s, vitem); print_view_item(s, vitem);
@ -533,7 +521,7 @@ fn print_item(&ps s, &@ast::item item) {
s.ann.post(ann_node); s.ann.post(ann_node);
} }
fn print_outer_attributes(&ps s, &ast::attribute[] attrs) { fn print_outer_attributes(&ps s, vec[ast::attribute] attrs) {
auto count = 0; auto count = 0;
for (ast::attribute attr in attrs) { for (ast::attribute attr in attrs) {
alt (attr.node.style) { alt (attr.node.style) {
@ -544,7 +532,7 @@ fn print_outer_attributes(&ps s, &ast::attribute[] attrs) {
if (count > 0) { hardbreak_if_not_bol(s); } if (count > 0) { hardbreak_if_not_bol(s); }
} }
fn print_inner_attributes(&ps s, &ast::attribute[] attrs) { fn print_inner_attributes(&ps s, vec[ast::attribute] attrs) {
auto count = 0; auto count = 0;
for (ast::attribute attr in attrs) { for (ast::attribute attr in attrs) {
alt (attr.node.style) { alt (attr.node.style) {
@ -1025,9 +1013,9 @@ fn print_path(&ps s, &ast::path path) {
if (first) { first = false; } else { word(s.s, "::"); } if (first) { first = false; } else { word(s.s, "::"); }
word(s.s, id); word(s.s, id);
} }
if (ivec::len(path.node.types) > 0u) { if (vec::len(path.node.types) > 0u) {
word(s.s, "["); word(s.s, "[");
commasep_ivec(s, inconsistent, path.node.types, print_boxed_type); commasep(s, inconsistent, path.node.types, print_boxed_type);
word(s.s, "]"); word(s.s, "]");
} }
} }
@ -1118,7 +1106,7 @@ fn print_meta_item(&ps s, &@ast::meta_item item) {
case (ast::meta_list(?name, ?items)) { case (ast::meta_list(?name, ?items)) {
word(s.s, name); word(s.s, name);
popen(s); popen(s);
commasep_ivec(s, consistent, items, print_meta_item); commasep(s, consistent, items, print_meta_item);
pclose(s); pclose(s);
} }
} }
@ -1132,9 +1120,9 @@ fn print_view_item(&ps s, &@ast::view_item item) {
case (ast::view_item_use(?id, ?mta, _)) { case (ast::view_item_use(?id, ?mta, _)) {
head(s, "use"); head(s, "use");
word(s.s, id); word(s.s, id);
if (ivec::len(mta) > 0u) { if (vec::len(mta) > 0u) {
popen(s); popen(s);
commasep_ivec(s, consistent, mta, print_meta_item); commasep(s, consistent, mta, print_meta_item);
pclose(s); pclose(s);
} }
} }
@ -1433,7 +1421,7 @@ fn next_comment(&ps s) -> option::t[lexer::cmnt] {
fn constr_args_to_str[T](fn(&T) -> str f, fn constr_args_to_str[T](fn(&T) -> str f,
&(@ast::constr_arg_general[T])[] args) -> str { &vec[@ast::constr_arg_general[T]] args) -> str {
auto comma = false; auto comma = false;
auto s = "("; auto s = "(";
for (@ast::constr_arg_general[T] a in args) { for (@ast::constr_arg_general[T] a in args) {
@ -1459,13 +1447,8 @@ fn constr_arg_to_str[T](fn(&T) -> str f, &ast::constr_arg_general_[T] c) ->
fn uint_to_str(&uint i) -> str { ret uint::str(i); } fn uint_to_str(&uint i) -> str { ret uint::str(i); }
fn ast_constr_to_str(&@ast::constr c) -> str { fn ast_constr_to_str(&@ast::constr c) -> str {
// TODO: Remove this vec->ivec conversion.
auto cag_ivec = ~[];
for (@ast::constr_arg_general[uint] cag in c.node.args) {
cag_ivec += ~[cag];
}
ret ast::path_to_str(c.node.path) + ret ast::path_to_str(c.node.path) +
constr_args_to_str(uint_to_str, cag_ivec); constr_args_to_str(uint_to_str, c.node.args);
} }
fn ast_constrs_str(&vec[@ast::constr] constrs) -> str { fn ast_constrs_str(&vec[@ast::constr] constrs) -> str {

View file

@ -1,7 +1,7 @@
// An "interner" is a data structure that associates values with uint tags and // An "interner" is a data structure that associates values with uint tags and
// allows bidirectional lookup; i.e. given a value, one can easily find the // allows bidirectional lookup; i.e. given a value, one can easily find the
// type, and vice versa. // type, and vice versa.
import std::ivec; import std::vec;
import std::map; import std::map;
import std::map::hashmap; import std::map::hashmap;
import std::map::hashfn; import std::map::hashfn;
@ -12,24 +12,24 @@ import std::option::some;
type interner[T] = type interner[T] =
rec(hashmap[T, uint] map, rec(hashmap[T, uint] map,
mutable T[] vect, mutable vec[T] vect,
hashfn[T] hasher, hashfn[T] hasher,
eqfn[T] eqer); eqfn[T] eqer);
fn mk[T](hashfn[T] hasher, eqfn[T] eqer) -> interner[T] { fn mk[T](hashfn[T] hasher, eqfn[T] eqer) -> interner[T] {
auto m = map::mk_hashmap[T, uint](hasher, eqer); auto m = map::mk_hashmap[T, uint](hasher, eqer);
ret rec(map=m, mutable vect=~[], hasher=hasher, eqer=eqer); let vec[T] vect = [];
ret rec(map=m, mutable vect=vect, hasher=hasher, eqer=eqer);
} }
fn intern[T](&interner[T] itr, &T val) -> uint { fn intern[T](&interner[T] itr, &T val) -> uint {
alt (itr.map.find(val)) { alt (itr.map.find(val)) {
case (some(?idx)) { ret idx; } case (some(?idx)) { ret idx; }
case (none) { case (none) {
auto new_idx = ivec::len[T](itr.vect); auto new_idx = vec::len[T](itr.vect);
itr.map.insert(val, new_idx); itr.map.insert(val, new_idx);
itr.vect += ~[val]; itr.vect += [val];
ret new_idx; ret new_idx;
} }
} }
} }
fn get[T](&interner[T] itr, uint idx) -> T { ret itr.vect.(idx); } fn get[T](&interner[T] itr, uint idx) -> T { ret itr.vect.(idx); }

View file

@ -1,5 +1,4 @@
import std::io; import std::io;
import std::ivec;
import std::vec; import std::vec;
import std::str; import std::str;
import std::int; import std::int;
@ -47,7 +46,7 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
} }
fn fn_to_str(&ctxt cx, ast::proto proto, option::t[ast::ident] ident, fn fn_to_str(&ctxt cx, ast::proto proto, option::t[ast::ident] ident,
&arg[] inputs, t output, ast::controlflow cf, &arg[] inputs, t output, ast::controlflow cf,
&(@constr_def)[] constrs) -> str { &vec[@constr_def] constrs) -> str {
auto s; auto s;
alt (proto) { alt (proto) {
case (ast::proto_iter) { s = "iter"; } case (ast::proto_iter) { s = "iter"; }
@ -119,9 +118,9 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
// The user should never see this if the cname is set properly! // The user should never see this if the cname is set properly!
s += "<tag#" + int::str(id._0) + ":" + int::str(id._1) + ">"; s += "<tag#" + int::str(id._0) + ":" + int::str(id._1) + ">";
if (ivec::len[t](tps) > 0u) { if (vec::len[t](tps) > 0u) {
let vec[str] strs = []; auto f = bind ty_to_str(cx, _);
for (t typ in tps) { strs += [ty_to_str(cx, typ)]; } auto strs = vec::map[t, str](f, tps);
s += "[" + str::connect(strs, ",") + "]"; s += "[" + str::connect(strs, ",") + "]";
} }
} }
@ -130,13 +129,12 @@ fn ty_to_str(&ctxt cx, &t typ) -> str {
} }
case (ty_native_fn(_, ?inputs, ?output)) { case (ty_native_fn(_, ?inputs, ?output)) {
s += fn_to_str(cx, ast::proto_fn, none, inputs, output, s += fn_to_str(cx, ast::proto_fn, none, inputs, output,
ast::return, ~[]); ast::return, []);
} }
case (ty_obj(?meths)) { case (ty_obj(?meths)) {
// TODO: Remove this ivec->vec conversion. auto f = bind method_to_str(cx, _);
auto strs = []; auto m = vec::map[method, str](f, meths);
for (method m in meths) { strs += [method_to_str(cx, m)]; } s += "obj {\n\t" + str::connect(m, "\n\t") + "\n}";
s += "obj {\n\t" + str::connect(strs, "\n\t") + "\n}";
} }
case (ty_res(?id, _, _)) { case (ty_res(?id, _, _)) {
s += "<resource#" + int::str(id._0) + ":" + int::str(id._1) + ">"; s += "<resource#" + int::str(id._0) + ":" + int::str(id._1) + ">";
@ -163,7 +161,7 @@ fn constr_to_str(&@constr_def c) -> str {
pprust::constr_args_to_str(pprust::uint_to_str, c.node.args); pprust::constr_args_to_str(pprust::uint_to_str, c.node.args);
} }
fn constrs_str(&(@constr_def)[] constrs) -> str { fn constrs_str(&vec[@constr_def] constrs) -> str {
auto s = ""; auto s = "";
auto colon = true; auto colon = true;
for (@constr_def c in constrs) { for (@constr_def c in constrs) {