Parse and typecheck by-value and by-ref arg specs
Add sprinkle && throughout the compiler to make it typecheck again. Issue #1008
This commit is contained in:
parent
4709038d64
commit
f9fbd86f52
32 changed files with 230 additions and 197 deletions
|
@ -57,7 +57,7 @@ fn get_attr_name(attr: ast::attribute) -> ast::ident {
|
||||||
fn find_meta_items_by_name(metas: [@ast::meta_item], name: ast::ident) ->
|
fn find_meta_items_by_name(metas: [@ast::meta_item], name: ast::ident) ->
|
||||||
[@ast::meta_item] {
|
[@ast::meta_item] {
|
||||||
let filter =
|
let filter =
|
||||||
bind fn (m: @ast::meta_item, name: ast::ident) ->
|
bind fn (&&m: @ast::meta_item, name: ast::ident) ->
|
||||||
option::t<@ast::meta_item> {
|
option::t<@ast::meta_item> {
|
||||||
if get_meta_item_name(m) == name {
|
if get_meta_item_name(m) == name {
|
||||||
option::some(m)
|
option::some(m)
|
||||||
|
@ -134,7 +134,7 @@ fn contains_name(metas: [@ast::meta_item], name: ast::ident) -> bool {
|
||||||
|
|
||||||
// FIXME: This needs to sort by meta_item variant in addition to the item name
|
// FIXME: This needs to sort by meta_item variant in addition to the item name
|
||||||
fn sort_meta_items(items: [@ast::meta_item]) -> [@ast::meta_item] {
|
fn sort_meta_items(items: [@ast::meta_item]) -> [@ast::meta_item] {
|
||||||
fn lteq(ma: @ast::meta_item, mb: @ast::meta_item) -> bool {
|
fn lteq(&&ma: @ast::meta_item, &&mb: @ast::meta_item) -> bool {
|
||||||
fn key(m: @ast::meta_item) -> ast::ident {
|
fn key(m: @ast::meta_item) -> ast::ident {
|
||||||
alt m.node {
|
alt m.node {
|
||||||
ast::meta_word(name) { name }
|
ast::meta_word(name) { name }
|
||||||
|
@ -160,7 +160,7 @@ fn remove_meta_items_by_name(items: [@ast::meta_item], name: str) ->
|
||||||
[@ast::meta_item] {
|
[@ast::meta_item] {
|
||||||
|
|
||||||
let filter =
|
let filter =
|
||||||
bind fn (item: @ast::meta_item, name: str) ->
|
bind fn (&&item: @ast::meta_item, name: str) ->
|
||||||
option::t<@ast::meta_item> {
|
option::t<@ast::meta_item> {
|
||||||
if get_meta_item_name(item) != name {
|
if get_meta_item_name(item) != name {
|
||||||
option::some(item)
|
option::some(item)
|
||||||
|
|
|
@ -20,7 +20,7 @@ fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
|
||||||
ret res;
|
ret res;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_item(cfg: ast::crate_cfg, item: @ast::item) ->
|
fn filter_item(cfg: ast::crate_cfg, &&item: @ast::item) ->
|
||||||
option::t<@ast::item> {
|
option::t<@ast::item> {
|
||||||
if item_in_cfg(cfg, item) { option::some(item) } else { option::none }
|
if item_in_cfg(cfg, item) { option::some(item) } else { option::none }
|
||||||
}
|
}
|
||||||
|
@ -29,11 +29,11 @@ fn fold_mod(cfg: ast::crate_cfg, m: ast::_mod, fld: fold::ast_fold) ->
|
||||||
ast::_mod {
|
ast::_mod {
|
||||||
let filter = bind filter_item(cfg, _);
|
let filter = bind filter_item(cfg, _);
|
||||||
let filtered_items = vec::filter_map(filter, m.items);
|
let filtered_items = vec::filter_map(filter, m.items);
|
||||||
ret {view_items: vec::map(fld.fold_view_item, m.view_items),
|
ret {view_items: vec::map_imm(fld.fold_view_item, m.view_items),
|
||||||
items: vec::map(fld.fold_item, filtered_items)};
|
items: vec::map_imm(fld.fold_item, filtered_items)};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_native_item(cfg: ast::crate_cfg, item: @ast::native_item) ->
|
fn filter_native_item(cfg: ast::crate_cfg, &&item: @ast::native_item) ->
|
||||||
option::t<@ast::native_item> {
|
option::t<@ast::native_item> {
|
||||||
if native_item_in_cfg(cfg, item) {
|
if native_item_in_cfg(cfg, item) {
|
||||||
option::some(item)
|
option::some(item)
|
||||||
|
@ -46,11 +46,11 @@ fn fold_native_mod(cfg: ast::crate_cfg, nm: ast::native_mod,
|
||||||
let filtered_items = vec::filter_map(filter, nm.items);
|
let filtered_items = vec::filter_map(filter, nm.items);
|
||||||
ret {native_name: nm.native_name,
|
ret {native_name: nm.native_name,
|
||||||
abi: nm.abi,
|
abi: nm.abi,
|
||||||
view_items: vec::map(fld.fold_view_item, nm.view_items),
|
view_items: vec::map_imm(fld.fold_view_item, nm.view_items),
|
||||||
items: filtered_items};
|
items: filtered_items};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn filter_stmt(cfg: ast::crate_cfg, stmt: @ast::stmt) ->
|
fn filter_stmt(cfg: ast::crate_cfg, &&stmt: @ast::stmt) ->
|
||||||
option::t<@ast::stmt> {
|
option::t<@ast::stmt> {
|
||||||
alt stmt.node {
|
alt stmt.node {
|
||||||
ast::stmt_decl(decl, _) {
|
ast::stmt_decl(decl, _) {
|
||||||
|
@ -71,8 +71,8 @@ fn fold_block(cfg: ast::crate_cfg, b: ast::blk_, fld: fold::ast_fold) ->
|
||||||
ast::blk_ {
|
ast::blk_ {
|
||||||
let filter = bind filter_stmt(cfg, _);
|
let filter = bind filter_stmt(cfg, _);
|
||||||
let filtered_stmts = vec::filter_map(filter, b.stmts);
|
let filtered_stmts = vec::filter_map(filter, b.stmts);
|
||||||
ret {stmts: vec::map(fld.fold_stmt, filtered_stmts),
|
ret {stmts: vec::map_imm(fld.fold_stmt, filtered_stmts),
|
||||||
expr: option::map(fld.fold_expr, b.expr),
|
expr: option::map_imm(fld.fold_expr, b.expr),
|
||||||
id: b.id,
|
id: b.id,
|
||||||
rules: b.rules};
|
rules: b.rules};
|
||||||
}
|
}
|
||||||
|
@ -97,21 +97,20 @@ fn in_cfg(cfg: ast::crate_cfg, attrs: [ast::attribute]) -> bool {
|
||||||
// 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
|
||||||
let item_cfg_metas =
|
let item_cfg_metas = {
|
||||||
{
|
fn extract_metas(inner_items: [@ast::meta_item],
|
||||||
fn extract_metas(inner_items: [@ast::meta_item],
|
&&cfg_item: @ast::meta_item) -> [@ast::meta_item] {
|
||||||
cfg_item: @ast::meta_item) -> [@ast::meta_item] {
|
alt cfg_item.node {
|
||||||
alt cfg_item.node {
|
ast::meta_list(name, items) {
|
||||||
ast::meta_list(name, items) {
|
assert (name == "cfg");
|
||||||
assert (name == "cfg");
|
inner_items + items
|
||||||
inner_items + items
|
}
|
||||||
}
|
_ { inner_items }
|
||||||
_ { inner_items }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let cfg_metas = attr::attr_metas(item_cfg_attrs);
|
}
|
||||||
vec::foldl(extract_metas, [], cfg_metas)
|
let cfg_metas = attr::attr_metas(item_cfg_attrs);
|
||||||
};
|
vec::foldl(extract_metas, [], cfg_metas)
|
||||||
|
};
|
||||||
|
|
||||||
for cfg_mi: @ast::meta_item in item_cfg_metas {
|
for cfg_mi: @ast::meta_item in item_cfg_metas {
|
||||||
if attr::contains(cfg, cfg_mi) { ret true; }
|
if attr::contains(cfg, cfg_mi) { ret true; }
|
||||||
|
|
|
@ -56,7 +56,7 @@ fn fold_mod(_cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod {
|
||||||
// the one we're going to add. FIXME: This is sloppy. Instead we should
|
// the one we're going to add. FIXME: This is sloppy. Instead we should
|
||||||
// have some mechanism to indicate to the translation pass which function
|
// have some mechanism to indicate to the translation pass which function
|
||||||
// we want to be main.
|
// we want to be main.
|
||||||
fn nomain(item: @ast::item) -> option::t<@ast::item> {
|
fn nomain(&&item: @ast::item) -> option::t<@ast::item> {
|
||||||
alt item.node {
|
alt item.node {
|
||||||
ast::item_fn(f, _) {
|
ast::item_fn(f, _) {
|
||||||
if item.ident == "main" {
|
if item.ident == "main" {
|
||||||
|
|
|
@ -909,9 +909,9 @@ obj type_names(type_names: std::map::hashmap<TypeRef, str>,
|
||||||
fn mk_type_names() -> type_names {
|
fn mk_type_names() -> type_names {
|
||||||
let nt = std::map::new_str_hash::<TypeRef>();
|
let nt = std::map::new_str_hash::<TypeRef>();
|
||||||
|
|
||||||
fn hash(t: TypeRef) -> uint { ret t as uint; }
|
fn hash(&&t: TypeRef) -> uint { ret t as uint; }
|
||||||
|
|
||||||
fn eq(a: TypeRef, b: TypeRef) -> bool { ret a as uint == b as uint; }
|
fn eq(&&a: TypeRef, &&b: TypeRef) -> bool { ret a as uint == b as uint; }
|
||||||
|
|
||||||
let hasher: std::map::hashfn<TypeRef> = hash;
|
let hasher: std::map::hashfn<TypeRef> = hash;
|
||||||
let eqer: std::map::eqfn<TypeRef> = eq;
|
let eqer: std::map::eqfn<TypeRef> = eq;
|
||||||
|
|
|
@ -65,7 +65,7 @@ const tag_crate_dep: uint = 0x26u;
|
||||||
const tag_items_data_item_inlineness: uint = 0x27u;
|
const tag_items_data_item_inlineness: uint = 0x27u;
|
||||||
|
|
||||||
// djb's cdb hashes.
|
// djb's cdb hashes.
|
||||||
fn hash_node_id(node_id: int) -> uint { ret 177573u ^ (node_id as uint); }
|
fn hash_node_id(&&node_id: int) -> uint { ret 177573u ^ (node_id as uint); }
|
||||||
|
|
||||||
fn hash_path(s: str) -> uint {
|
fn hash_path(s: str) -> uint {
|
||||||
let h = 5381u;
|
let h = 5381u;
|
||||||
|
|
|
@ -427,7 +427,7 @@ fn encode_index<T>(ebml_w: ebml::writer, buckets: [@[entry<T>]],
|
||||||
|
|
||||||
fn write_str(writer: io::writer, s: str) { writer.write_str(s); }
|
fn write_str(writer: io::writer, s: str) { writer.write_str(s); }
|
||||||
|
|
||||||
fn write_int(writer: io::writer, n: int) {
|
fn write_int(writer: io::writer, &&n: int) {
|
||||||
writer.write_be_uint(n as uint, 4u);
|
writer.write_be_uint(n as uint, 4u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -380,14 +380,13 @@ fn parse_ty_fn(st: @pstate, sd: str_def) ->
|
||||||
assert (next(st) as char == '[');
|
assert (next(st) as char == '[');
|
||||||
let inputs: [ty::arg] = [];
|
let inputs: [ty::arg] = [];
|
||||||
while peek(st) as char != ']' {
|
while peek(st) as char != ']' {
|
||||||
let mode = ast::by_ref;
|
let mode = alt peek(st) as char {
|
||||||
if peek(st) as char == '&' {
|
'&' { ast::by_mut_ref }
|
||||||
mode = ast::by_mut_ref;
|
'-' { ast::by_move }
|
||||||
st.pos += 1u;
|
'=' { ast::by_ref }
|
||||||
} else if peek(st) as char == '-' {
|
'+' { ast::by_val }
|
||||||
mode = ast::by_move;
|
};
|
||||||
st.pos += 1u;
|
st.pos += 1u;
|
||||||
}
|
|
||||||
inputs += [{mode: mode, ty: parse_ty(st, sd)}];
|
inputs += [{mode: mode, ty: parse_ty(st, sd)}];
|
||||||
}
|
}
|
||||||
st.pos += 1u; // eat the ']'
|
st.pos += 1u; // eat the ']'
|
||||||
|
|
|
@ -207,7 +207,8 @@ fn enc_ty_fn(w: io::writer, cx: @ctxt, args: [ty::arg], out: ty::t,
|
||||||
alt arg.mode {
|
alt arg.mode {
|
||||||
by_mut_ref. { w.write_char('&'); }
|
by_mut_ref. { w.write_char('&'); }
|
||||||
by_move. { w.write_char('-'); }
|
by_move. { w.write_char('-'); }
|
||||||
by_ref. { }
|
by_ref. { w.write_char('='); }
|
||||||
|
by_val. { w.write_char('+'); }
|
||||||
}
|
}
|
||||||
enc_ty(w, cx, arg.ty);
|
enc_ty(w, cx, arg.ty);
|
||||||
}
|
}
|
||||||
|
|
|
@ -251,10 +251,8 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [binding] {
|
||||||
mutable ok: valid,
|
mutable ok: valid,
|
||||||
mutable copied: alt arg_t.mode {
|
mutable copied: alt arg_t.mode {
|
||||||
ast::by_move. { copied }
|
ast::by_move. { copied }
|
||||||
ast::by_ref. {
|
|
||||||
i + 1u == by_ref ? not_allowed : not_copied
|
|
||||||
}
|
|
||||||
ast::by_mut_ref. { not_allowed }
|
ast::by_mut_ref. { not_allowed }
|
||||||
|
_ { i + 1u == by_ref ? not_allowed : not_copied }
|
||||||
}}];
|
}}];
|
||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,7 @@ fn map_expr(cx: ctx, ex: @expr) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_smallintmap_int_adapter<@V>() -> std::map::hashmap<int, V> {
|
fn new_smallintmap_int_adapter<@V>() -> std::map::hashmap<int, V> {
|
||||||
let key_idx = fn (key: int) -> uint { key as uint };
|
let key_idx = fn (&&key: int) -> uint { key as uint };
|
||||||
let idx_key = fn (idx: uint) -> int { idx as int };
|
let idx_key = fn (idx: uint) -> int { idx as int };
|
||||||
ret new_smallintmap_adapter(key_idx, idx_key);
|
ret new_smallintmap_adapter(key_idx, idx_key);
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
|
||||||
tcx.sess.abort_if_errors();
|
tcx.sess.abort_if_errors();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_expr(tcx: ty::ctxt, ex: @expr, s: (), v: visit::vt<()>) {
|
fn check_expr(tcx: ty::ctxt, ex: @expr, &&s: (), v: visit::vt<()>) {
|
||||||
visit::visit_expr(ex, s, v);
|
visit::visit_expr(ex, s, v);
|
||||||
alt ex.node { expr_alt(_, arms) { check_arms(tcx, arms); } _ { } }
|
alt ex.node { expr_alt(_, arms) { check_arms(tcx, arms); } _ { } }
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ fn pattern_supersedes(tcx: ty::ctxt, a: @pat, b: @pat) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_local(tcx: ty::ctxt, loc: @local, s: (), v: visit::vt<()>) {
|
fn check_local(tcx: ty::ctxt, loc: @local, &&s: (), v: visit::vt<()>) {
|
||||||
visit::visit_local(loc, s, v);
|
visit::visit_local(loc, s, v);
|
||||||
if is_refutable(tcx, loc.node.pat) {
|
if is_refutable(tcx, loc.node.pat) {
|
||||||
tcx.sess.span_err(loc.node.pat.span,
|
tcx.sess.span_err(loc.node.pat.span,
|
||||||
|
|
|
@ -29,10 +29,10 @@ fn collect_freevars(def_map: resolve::def_map, walker: fn(visit::vt<int>)) ->
|
||||||
let seen = new_int_hash();
|
let seen = new_int_hash();
|
||||||
let refs = @mutable [];
|
let refs = @mutable [];
|
||||||
|
|
||||||
fn ignore_item(_i: @ast::item, _depth: int, _v: visit::vt<int>) { }
|
fn ignore_item(_i: @ast::item, &&_depth: int, _v: visit::vt<int>) { }
|
||||||
|
|
||||||
let walk_expr =
|
let walk_expr =
|
||||||
lambda (expr: @ast::expr, depth: int, v: visit::vt<int>) {
|
lambda (expr: @ast::expr, &&depth: int, v: visit::vt<int>) {
|
||||||
alt expr.node {
|
alt expr.node {
|
||||||
ast::expr_fn(f) {
|
ast::expr_fn(f) {
|
||||||
if f.proto == ast::proto_block ||
|
if f.proto == ast::proto_block ||
|
||||||
|
|
|
@ -131,7 +131,7 @@ fn mk_err(cx: @ctx, span: syntax::codemap::span, msg: msg, name: str) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_decl(cx: @ctx, d: @decl, e: (), v: visit::vt<()>) {
|
fn visit_decl(cx: @ctx, d: @decl, &&e: (), v: visit::vt<()>) {
|
||||||
visit::visit_decl(d, e, v);
|
visit::visit_decl(d, e, v);
|
||||||
alt d.node {
|
alt d.node {
|
||||||
decl_local(locs) {
|
decl_local(locs) {
|
||||||
|
@ -148,7 +148,7 @@ fn visit_decl(cx: @ctx, d: @decl, e: (), v: visit::vt<()>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_expr(cx: @ctx, ex: @expr, e: (), v: visit::vt<()>) {
|
fn visit_expr(cx: @ctx, ex: @expr, &&e: (), v: visit::vt<()>) {
|
||||||
alt ex.node {
|
alt ex.node {
|
||||||
expr_call(f, args) { check_call(cx, f, args); }
|
expr_call(f, args) { check_call(cx, f, args); }
|
||||||
expr_swap(lhs, rhs) {
|
expr_swap(lhs, rhs) {
|
||||||
|
@ -225,7 +225,7 @@ fn check_call(cx: @ctx, f: @expr, args: [@expr]) {
|
||||||
alt arg_t.mode {
|
alt arg_t.mode {
|
||||||
by_mut_ref. { check_lval(cx, args[i], msg_mut_ref); }
|
by_mut_ref. { check_lval(cx, args[i], msg_mut_ref); }
|
||||||
by_move. { check_lval(cx, args[i], msg_move_out); }
|
by_move. { check_lval(cx, args[i], msg_move_out); }
|
||||||
by_ref. {}
|
_ {}
|
||||||
}
|
}
|
||||||
i += 1u;
|
i += 1u;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1239,7 +1239,7 @@ fn mie_span(mie: mod_index_entry) -> span {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_item(e: @env, i: @ast::item, x: (), v: vt<()>) {
|
fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) {
|
||||||
fn typaram_names(tps: [ast::ty_param]) -> [ident] {
|
fn typaram_names(tps: [ast::ty_param]) -> [ident] {
|
||||||
let x: [ast::ident] = [];
|
let x: [ast::ident] = [];
|
||||||
for tp: ast::ty_param in tps { x += [tp.ident]; }
|
for tp: ast::ty_param in tps { x += [tp.ident]; }
|
||||||
|
@ -1276,7 +1276,7 @@ fn check_pat(ch: checker, p: @ast::pat) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_arm(e: @env, a: ast::arm, x: (), v: vt<()>) {
|
fn check_arm(e: @env, a: ast::arm, &&x: (), v: vt<()>) {
|
||||||
visit::visit_arm(a, x, v);
|
visit::visit_arm(a, x, v);
|
||||||
let ch0 = checker(*e, "binding");
|
let ch0 = checker(*e, "binding");
|
||||||
check_pat(ch0, a.pats[0]);
|
check_pat(ch0, a.pats[0]);
|
||||||
|
@ -1306,7 +1306,7 @@ fn check_arm(e: @env, a: ast::arm, x: (), v: vt<()>) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_block(e: @env, b: ast::blk, x: (), v: vt<()>) {
|
fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
|
||||||
visit::visit_block(b, x, v);
|
visit::visit_block(b, x, v);
|
||||||
let values = checker(*e, "value");
|
let values = checker(*e, "value");
|
||||||
let types = checker(*e, "type");
|
let types = checker(*e, "type");
|
||||||
|
@ -1359,7 +1359,7 @@ fn check_fn(e: env, sp: span, f: ast::_fn) {
|
||||||
ensure_unique(e, sp, f.decl.inputs, arg_name, "argument");
|
ensure_unique(e, sp, f.decl.inputs, arg_name, "argument");
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_expr(e: @env, ex: @ast::expr, x: (), v: vt<()>) {
|
fn check_expr(e: @env, ex: @ast::expr, &&x: (), v: vt<()>) {
|
||||||
alt ex.node {
|
alt ex.node {
|
||||||
ast::expr_rec(fields, _) {
|
ast::expr_rec(fields, _) {
|
||||||
fn field_name(f: ast::field) -> ident { ret f.node.ident; }
|
fn field_name(f: ast::field) -> ident { ret f.node.ident; }
|
||||||
|
@ -1370,7 +1370,7 @@ fn check_expr(e: @env, ex: @ast::expr, x: (), v: vt<()>) {
|
||||||
visit::visit_expr(ex, x, v);
|
visit::visit_expr(ex, x, v);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_ty(e: @env, ty: @ast::ty, x: (), v: vt<()>) {
|
fn check_ty(e: @env, ty: @ast::ty, &&x: (), v: vt<()>) {
|
||||||
alt ty.node {
|
alt ty.node {
|
||||||
ast::ty_rec(fields) {
|
ast::ty_rec(fields) {
|
||||||
fn field_name(f: ast::ty_field) -> ident { ret f.node.ident; }
|
fn field_name(f: ast::ty_field) -> ident { ret f.node.ident; }
|
||||||
|
|
|
@ -3699,7 +3699,7 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
|
||||||
// be inspected. It's important for the value
|
// be inspected. It's important for the value
|
||||||
// to have type lldestty0 (the callee's expected type).
|
// to have type lldestty0 (the callee's expected type).
|
||||||
val = llvm::LLVMGetUndef(lldestty0);
|
val = llvm::LLVMGetUndef(lldestty0);
|
||||||
} else if arg.mode == ast::by_ref {
|
} else if arg.mode == ast::by_ref || arg.mode == ast::by_val {
|
||||||
let copied = false;
|
let copied = false;
|
||||||
if !lv.is_mem && type_is_immediate(ccx, e_ty) {
|
if !lv.is_mem && type_is_immediate(ccx, e_ty) {
|
||||||
val = do_spill_noroot(bcx, val);
|
val = do_spill_noroot(bcx, val);
|
||||||
|
@ -4439,9 +4439,9 @@ fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
|
||||||
// latter group "immediates" and, in some circumstances when we know we have a
|
// latter group "immediates" and, in some circumstances when we know we have a
|
||||||
// pointer (or need one), perform load/store operations based on the
|
// pointer (or need one), perform load/store operations based on the
|
||||||
// immediate-ness of the type.
|
// immediate-ness of the type.
|
||||||
|
// FIXME simply call the version in ty.rs immediately
|
||||||
fn type_is_immediate(ccx: @crate_ctxt, t: ty::t) -> bool {
|
fn type_is_immediate(ccx: @crate_ctxt, t: ty::t) -> bool {
|
||||||
ret ty::type_is_scalar(ccx.tcx, t) || ty::type_is_boxed(ccx.tcx, t) ||
|
ty::type_is_immediate(ccx.tcx, t)
|
||||||
ty::type_is_unique_box(ccx.tcx, t) || ty::type_is_native(ccx.tcx, t);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn do_spill(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result {
|
fn do_spill(cx: @block_ctxt, v: ValueRef, t: ty::t) -> result {
|
||||||
|
@ -5144,7 +5144,11 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
|
||||||
for aarg: ast::arg in args {
|
for aarg: ast::arg in args {
|
||||||
let arg_ty = arg_tys[arg_n].ty;
|
let arg_ty = arg_tys[arg_n].ty;
|
||||||
alt aarg.mode {
|
alt aarg.mode {
|
||||||
ast::by_ref. {
|
ast::by_move. {
|
||||||
|
add_clean(bcx, fcx.llargs.get(aarg.id), arg_ty);
|
||||||
|
}
|
||||||
|
ast::by_mut_ref. { }
|
||||||
|
_ {
|
||||||
let mutated =
|
let mutated =
|
||||||
!ignore_mut && fcx.lcx.ccx.mut_map.contains_key(aarg.id);
|
!ignore_mut && fcx.lcx.ccx.mut_map.contains_key(aarg.id);
|
||||||
|
|
||||||
|
@ -5160,10 +5164,6 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
|
||||||
add_clean(bcx, alloc, arg_ty);
|
add_clean(bcx, alloc, arg_ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::by_move. {
|
|
||||||
add_clean(bcx, fcx.llargs.get(aarg.id), arg_ty);
|
|
||||||
}
|
|
||||||
_ { }
|
|
||||||
}
|
}
|
||||||
arg_n += 1u;
|
arg_n += 1u;
|
||||||
}
|
}
|
||||||
|
@ -5790,7 +5790,7 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
|
||||||
}
|
}
|
||||||
fn convert_arg_to_i32(cx: @block_ctxt, v: ValueRef, t: ty::t,
|
fn convert_arg_to_i32(cx: @block_ctxt, v: ValueRef, t: ty::t,
|
||||||
mode: ty::mode) -> ValueRef {
|
mode: ty::mode) -> ValueRef {
|
||||||
if mode == ast::by_ref {
|
if mode == ast::by_ref || mode == ast::by_val {
|
||||||
if ty::type_is_integral(bcx_tcx(cx), t) {
|
if ty::type_is_integral(bcx_tcx(cx), t) {
|
||||||
// FIXME: would be nice to have a postcondition that says
|
// FIXME: would be nice to have a postcondition that says
|
||||||
// if a type is integral, then it has static size (#586)
|
// if a type is integral, then it has static size (#586)
|
||||||
|
@ -5845,7 +5845,7 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
|
||||||
let i = arg_n;
|
let i = arg_n;
|
||||||
for arg: ty::arg in args {
|
for arg: ty::arg in args {
|
||||||
let llarg = llvm::LLVMGetParam(fcx.llfn, i);
|
let llarg = llvm::LLVMGetParam(fcx.llfn, i);
|
||||||
if arg.mode == ast::by_ref {
|
if arg.mode == ast::by_ref || arg.mode == ast::by_val {
|
||||||
llarg = load_if_immediate(bcx, llarg, arg.ty);
|
llarg = load_if_immediate(bcx, llarg, arg.ty);
|
||||||
}
|
}
|
||||||
assert (llarg as int != 0);
|
assert (llarg as int != 0);
|
||||||
|
|
|
@ -41,7 +41,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
|
||||||
// we're creating.
|
// we're creating.
|
||||||
let fn_args: [ast::arg] = [];
|
let fn_args: [ast::arg] = [];
|
||||||
for f: ast::obj_field in ob.fields {
|
for f: ast::obj_field in ob.fields {
|
||||||
fn_args += [{mode: ast::by_ref, ty: f.ty, ident: f.ident, id: f.id}];
|
fn_args += [{mode: ast::by_ref, ty: f.ty, ident: f.ident,
|
||||||
|
id: f.id}];
|
||||||
}
|
}
|
||||||
let fcx = new_fn_ctxt(cx, sp, llctor_decl);
|
let fcx = new_fn_ctxt(cx, sp, llctor_decl);
|
||||||
|
|
||||||
|
@ -397,7 +398,7 @@ tag vtbl_mthd {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Alphabetize ast::methods by ident. A helper for create_vtbl.
|
// Alphabetize ast::methods by ident. A helper for create_vtbl.
|
||||||
fn ast_mthd_lteq(a: @ast::method, b: @ast::method) -> bool {
|
fn ast_mthd_lteq(&&a: @ast::method, &&b: @ast::method) -> bool {
|
||||||
ret str::lteq(a.node.ident, b.node.ident);
|
ret str::lteq(a.node.ident, b.node.ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,10 +99,10 @@ fn find_pre_post_exprs(fcx: fn_ctxt, args: [@expr], id: node_id) {
|
||||||
fn get_pp(ccx: crate_ctxt, e: @expr) -> pre_and_post {
|
fn get_pp(ccx: crate_ctxt, e: @expr) -> pre_and_post {
|
||||||
ret expr_pp(ccx, e);
|
ret expr_pp(ccx, e);
|
||||||
}
|
}
|
||||||
let pps = vec::map::<@expr, pre_and_post>(bind get_pp(fcx.ccx, _), args);
|
let pps = vec::map_imm(bind get_pp(fcx.ccx, _), args);
|
||||||
|
|
||||||
set_pre_and_post(fcx.ccx, id, seq_preconds(fcx, pps),
|
set_pre_and_post(fcx.ccx, id, seq_preconds(fcx, pps),
|
||||||
seq_postconds(fcx, vec::map(get_post, pps)));
|
seq_postconds(fcx, vec::map_imm(get_post, pps)));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn find_pre_post_loop(fcx: fn_ctxt, l: @local, index: @expr, body: blk,
|
fn find_pre_post_loop(fcx: fn_ctxt, l: @local, index: @expr, body: blk,
|
||||||
|
@ -476,8 +476,8 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
|
||||||
}
|
}
|
||||||
let alt_pps = [];
|
let alt_pps = [];
|
||||||
for a: arm in alts { alt_pps += [do_an_alt(fcx, a)]; }
|
for a: arm in alts { alt_pps += [do_an_alt(fcx, a)]; }
|
||||||
fn combine_pp(antec: pre_and_post, fcx: fn_ctxt, pp: pre_and_post,
|
fn combine_pp(antec: pre_and_post, fcx: fn_ctxt, &&pp: pre_and_post,
|
||||||
next: pre_and_post) -> pre_and_post {
|
&&next: pre_and_post) -> 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;
|
||||||
|
@ -694,7 +694,7 @@ fn find_pre_post_block(fcx: fn_ctxt, b: blk) {
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
for s: @stmt in b.node.stmts { do_one_(fcx, s); }
|
for s: @stmt in b.node.stmts { do_one_(fcx, s); }
|
||||||
fn do_inner_(fcx: fn_ctxt, e: @expr) { find_pre_post_expr(fcx, e); }
|
fn do_inner_(fcx: fn_ctxt, &&e: @expr) { find_pre_post_expr(fcx, e); }
|
||||||
let do_inner = bind do_inner_(fcx, _);
|
let do_inner = bind do_inner_(fcx, _);
|
||||||
option::map::<@expr, ()>(do_inner, b.node.expr);
|
option::map::<@expr, ()>(do_inner, b.node.expr);
|
||||||
|
|
||||||
|
|
|
@ -160,6 +160,7 @@ export type_is_native;
|
||||||
export type_is_nil;
|
export type_is_nil;
|
||||||
export type_is_pod;
|
export type_is_pod;
|
||||||
export type_is_scalar;
|
export type_is_scalar;
|
||||||
|
export type_is_immediate;
|
||||||
export type_is_sequence;
|
export type_is_sequence;
|
||||||
export type_is_signed;
|
export type_is_signed;
|
||||||
export type_is_structural;
|
export type_is_structural;
|
||||||
|
@ -916,6 +917,12 @@ pure fn type_is_scalar(cx: ctxt, ty: t) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME maybe inline this for speed?
|
||||||
|
fn type_is_immediate(cx: ctxt, ty: t) -> bool {
|
||||||
|
ret type_is_scalar(cx, ty) || type_is_boxed(cx, ty) ||
|
||||||
|
type_is_unique_box(cx, ty) || type_is_native(cx, ty);
|
||||||
|
}
|
||||||
|
|
||||||
fn type_has_pointers(cx: ctxt, ty: t) -> bool {
|
fn type_has_pointers(cx: ctxt, ty: t) -> bool {
|
||||||
alt cx.has_pointer_cache.find(ty) {
|
alt cx.has_pointer_cache.find(ty) {
|
||||||
some(result) { ret result; }
|
some(result) { ret result; }
|
||||||
|
@ -924,14 +931,8 @@ fn type_has_pointers(cx: ctxt, ty: t) -> bool {
|
||||||
|
|
||||||
let result = false;
|
let result = false;
|
||||||
alt struct(cx, ty) {
|
alt struct(cx, ty) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// scalar types
|
// scalar types
|
||||||
ty_nil. {
|
ty_nil. {/* no-op */ }
|
||||||
/* no-op */
|
|
||||||
|
|
||||||
}
|
|
||||||
ty_bot. {/* no-op */ }
|
ty_bot. {/* no-op */ }
|
||||||
ty_bool. {/* no-op */ }
|
ty_bool. {/* no-op */ }
|
||||||
ty_int. {/* no-op */ }
|
ty_int. {/* no-op */ }
|
||||||
|
@ -1446,14 +1447,14 @@ fn hash_type_info(st: sty, cname_opt: option::t<str>) -> uint {
|
||||||
ret h;
|
ret h;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn hash_raw_ty(rt: @raw_t) -> uint { ret rt.hash; }
|
fn hash_raw_ty(&&rt: @raw_t) -> uint { ret rt.hash; }
|
||||||
|
|
||||||
fn hash_ty(typ: t) -> uint { ret typ; }
|
fn hash_ty(&&typ: t) -> uint { ret typ; }
|
||||||
|
|
||||||
|
|
||||||
// Type equality. This function is private to this module (and slow); external
|
// Type equality. This function is private to this module (and slow); external
|
||||||
// users should use `eq_ty()` instead.
|
// users should use `eq_ty()` instead.
|
||||||
fn eq_int(x: uint, y: uint) -> bool { ret x == y; }
|
fn eq_int(&&x: uint, &&y: uint) -> bool { ret x == y; }
|
||||||
|
|
||||||
fn arg_eq<T>(eq: fn(T, T) -> bool, a: @sp_constr_arg<T>, b: @sp_constr_arg<T>)
|
fn arg_eq<T>(eq: fn(T, T) -> bool, a: @sp_constr_arg<T>, b: @sp_constr_arg<T>)
|
||||||
-> bool {
|
-> bool {
|
||||||
|
@ -1495,7 +1496,7 @@ fn constrs_eq(cs: [@constr], ds: [@constr]) -> bool {
|
||||||
|
|
||||||
// An expensive type equality function. This function is private to this
|
// An expensive type equality function. This function is private to this
|
||||||
// module.
|
// module.
|
||||||
fn eq_raw_ty(a: @raw_t, b: @raw_t) -> bool {
|
fn eq_raw_ty(&&a: @raw_t, &&b: @raw_t) -> bool {
|
||||||
// Check hashes (fast path).
|
// Check hashes (fast path).
|
||||||
|
|
||||||
if a.hash != b.hash { ret false; }
|
if a.hash != b.hash { ret false; }
|
||||||
|
@ -1518,7 +1519,7 @@ fn eq_raw_ty(a: @raw_t, b: @raw_t) -> bool {
|
||||||
|
|
||||||
// This is the equality function the public should use. It works as long as
|
// This is the equality function the public should use. It works as long as
|
||||||
// the types are interned.
|
// the types are interned.
|
||||||
fn eq_ty(a: t, b: t) -> bool { ret a == b; }
|
fn eq_ty(&&a: t, &&b: t) -> bool { ret a == b; }
|
||||||
|
|
||||||
|
|
||||||
// Type lookups
|
// Type lookups
|
||||||
|
@ -1954,12 +1955,15 @@ mod unify {
|
||||||
let actual_input = actual_inputs[i];
|
let actual_input = actual_inputs[i];
|
||||||
// Unify the result modes.
|
// Unify the result modes.
|
||||||
|
|
||||||
let result_mode;
|
let result_mode = if expected_input.mode == ast::mode_infer {
|
||||||
if expected_input.mode != actual_input.mode {
|
actual_input.mode
|
||||||
|
} else if actual_input.mode == ast::mode_infer {
|
||||||
|
expected_input.mode
|
||||||
|
} else if expected_input.mode != actual_input.mode {
|
||||||
ret fn_common_res_err
|
ret fn_common_res_err
|
||||||
(ures_err(terr_mode_mismatch(expected_input.mode,
|
(ures_err(terr_mode_mismatch(expected_input.mode,
|
||||||
actual_input.mode)));
|
actual_input.mode)));
|
||||||
} else { result_mode = expected_input.mode; }
|
} else { expected_input.mode };
|
||||||
let result = unify_step(cx, expected_input.ty, actual_input.ty);
|
let result = unify_step(cx, expected_input.ty, actual_input.ty);
|
||||||
alt result {
|
alt result {
|
||||||
ures_ok(rty) { result_ins += [{mode: result_mode, ty: rty}]; }
|
ures_ok(rty) { result_ins += [{mode: result_mode, ty: rty}]; }
|
||||||
|
|
|
@ -224,7 +224,27 @@ fn type_is_scalar(fcx: @fn_ctxt, sp: span, typ: ty::t) -> bool {
|
||||||
// Parses the programmer's textual representation of a type into our internal
|
// Parses the programmer's textual representation of a type into our internal
|
||||||
// notion of a type. `getter` is a function that returns the type
|
// notion of a type. `getter` is a function that returns the type
|
||||||
// corresponding to a definition ID:
|
// corresponding to a definition ID:
|
||||||
|
fn default_arg_mode_for_ty(tcx: ty::ctxt, m: ast::mode,
|
||||||
|
ty: ty::t) -> ast::mode {
|
||||||
|
alt m {
|
||||||
|
ast::mode_infer. {
|
||||||
|
alt ty::struct(tcx, ty) {
|
||||||
|
ty::ty_var(_) { ast::mode_infer }
|
||||||
|
_ {
|
||||||
|
if ty::type_is_immediate(tcx, ty) { ast::by_val }
|
||||||
|
else { ast::by_ref }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_ { m }
|
||||||
|
}
|
||||||
|
}
|
||||||
fn ast_ty_to_ty(tcx: ty::ctxt, getter: ty_getter, ast_ty: @ast::ty) -> ty::t {
|
fn ast_ty_to_ty(tcx: ty::ctxt, getter: ty_getter, ast_ty: @ast::ty) -> ty::t {
|
||||||
|
fn ast_arg_to_arg(tcx: ty::ctxt, getter: ty_getter, arg: ast::ty_arg)
|
||||||
|
-> {mode: ty::mode, ty: ty::t} {
|
||||||
|
let ty = ast_ty_to_ty(tcx, getter, arg.node.ty);
|
||||||
|
ret {mode: default_arg_mode_for_ty(tcx, arg.node.mode, ty), ty: ty};
|
||||||
|
}
|
||||||
alt tcx.ast_ty_to_ty_cache.find(ast_ty) {
|
alt tcx.ast_ty_to_ty_cache.find(ast_ty) {
|
||||||
some(some(ty)) { ret ty; }
|
some(some(ty)) { ret ty; }
|
||||||
some(none.) {
|
some(none.) {
|
||||||
|
@ -237,10 +257,6 @@ fn ast_ty_to_ty(tcx: ty::ctxt, getter: ty_getter, ast_ty: @ast::ty) -> ty::t {
|
||||||
} /* go on */
|
} /* go on */
|
||||||
|
|
||||||
tcx.ast_ty_to_ty_cache.insert(ast_ty, none::<ty::t>);
|
tcx.ast_ty_to_ty_cache.insert(ast_ty, none::<ty::t>);
|
||||||
fn ast_arg_to_arg(tcx: ty::ctxt, getter: ty_getter, arg: ast::ty_arg) ->
|
|
||||||
{mode: ty::mode, ty: ty::t} {
|
|
||||||
ret {mode: arg.node.mode, ty: ast_ty_to_ty(tcx, getter, arg.node.ty)};
|
|
||||||
}
|
|
||||||
fn ast_mt_to_mt(tcx: ty::ctxt, getter: ty_getter, mt: ast::mt) -> ty::mt {
|
fn ast_mt_to_mt(tcx: ty::ctxt, getter: ty_getter, mt: ast::mt) -> ty::mt {
|
||||||
ret {ty: ast_ty_to_ty(tcx, getter, mt.ty), mut: mt.mut};
|
ret {ty: ast_ty_to_ty(tcx, getter, mt.ty), mut: mt.mut};
|
||||||
}
|
}
|
||||||
|
@ -295,7 +311,7 @@ fn ast_ty_to_ty(tcx: ty::ctxt, getter: ty_getter, ast_ty: @ast::ty) -> ty::t {
|
||||||
typ = ty::mk_ptr(tcx, ast_mt_to_mt(tcx, getter, mt));
|
typ = ty::mk_ptr(tcx, ast_mt_to_mt(tcx, getter, mt));
|
||||||
}
|
}
|
||||||
ast::ty_tup(fields) {
|
ast::ty_tup(fields) {
|
||||||
let flds = vec::map(bind ast_ty_to_ty(tcx, getter, _), fields);
|
let flds = vec::map_imm(bind ast_ty_to_ty(tcx, getter, _), fields);
|
||||||
typ = ty::mk_tup(tcx, flds);
|
typ = ty::mk_tup(tcx, flds);
|
||||||
}
|
}
|
||||||
ast::ty_rec(fields) {
|
ast::ty_rec(fields) {
|
||||||
|
@ -550,9 +566,8 @@ mod collect {
|
||||||
ret tpt;
|
ret tpt;
|
||||||
}
|
}
|
||||||
fn ty_of_arg(cx: @ctxt, a: ast::arg) -> ty::arg {
|
fn ty_of_arg(cx: @ctxt, a: ast::arg) -> ty::arg {
|
||||||
let f = bind getter(cx, _);
|
let ty = ast_ty_to_ty(cx.tcx, bind getter(cx, _), a.ty);
|
||||||
let tt = ast_ty_to_ty(cx.tcx, f, a.ty);
|
{mode: default_arg_mode_for_ty(cx.tcx, a.mode, ty), ty: ty}
|
||||||
ret {mode: a.mode, ty: tt};
|
|
||||||
}
|
}
|
||||||
fn ty_of_method(cx: @ctxt, m: @ast::method) -> ty::method {
|
fn ty_of_method(cx: @ctxt, m: @ast::method) -> ty::method {
|
||||||
let get = bind getter(cx, _);
|
let get = bind getter(cx, _);
|
||||||
|
@ -1216,7 +1231,7 @@ fn gather_locals(ccx: @crate_ctxt, f: ast::_fn, id: ast::node_id,
|
||||||
|
|
||||||
// Add explicitly-declared locals.
|
// Add explicitly-declared locals.
|
||||||
let visit_local =
|
let visit_local =
|
||||||
lambda (local: @ast::local, e: (), v: visit::vt<()>) {
|
lambda (local: @ast::local, &&e: (), v: visit::vt<()>) {
|
||||||
let local_ty = ast_ty_to_ty_crate_infer(ccx, local.node.ty);
|
let local_ty = ast_ty_to_ty_crate_infer(ccx, local.node.ty);
|
||||||
assign(local.node.id, ident_for_local(local), local_ty);
|
assign(local.node.id, ident_for_local(local), local_ty);
|
||||||
visit::visit_local(local, e, v);
|
visit::visit_local(local, e, v);
|
||||||
|
@ -1224,7 +1239,7 @@ fn gather_locals(ccx: @crate_ctxt, f: ast::_fn, id: ast::node_id,
|
||||||
|
|
||||||
// Add pattern bindings.
|
// Add pattern bindings.
|
||||||
let visit_pat =
|
let visit_pat =
|
||||||
lambda (p: @ast::pat, e: (), v: visit::vt<()>) {
|
lambda (p: @ast::pat, &&e: (), v: visit::vt<()>) {
|
||||||
alt p.node {
|
alt p.node {
|
||||||
ast::pat_bind(ident) { assign(p.id, ident, none); }
|
ast::pat_bind(ident) { assign(p.id, ident, none); }
|
||||||
_ {/* no-op */ }
|
_ {/* no-op */ }
|
||||||
|
@ -2022,16 +2037,16 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
||||||
write::ty_only_fixup(fcx, id, result_ty);
|
write::ty_only_fixup(fcx, id, result_ty);
|
||||||
}
|
}
|
||||||
ast::expr_fn(f) {
|
ast::expr_fn(f) {
|
||||||
let cx = @{tcx: tcx};
|
|
||||||
let convert = bind ast_ty_to_ty_crate_tyvar(fcx, _);
|
let convert = bind ast_ty_to_ty_crate_tyvar(fcx, _);
|
||||||
let ty_of_arg =
|
let ty_of_arg = lambda (a: ast::arg) -> ty::arg {
|
||||||
lambda (a: ast::arg) -> ty::arg {
|
let tt = ast_ty_to_ty_crate_tyvar(fcx, a.ty);
|
||||||
let tt = ast_ty_to_ty_crate_tyvar(fcx, a.ty);
|
ret {mode: default_arg_mode_for_ty(fcx.ccx.tcx, a.mode, tt),
|
||||||
ret {mode: a.mode, ty: tt};
|
ty: tt};
|
||||||
};
|
};
|
||||||
let fty =
|
let cx = @{tcx: tcx};
|
||||||
collect::ty_of_fn_decl(cx, convert, ty_of_arg, f.decl, f.proto,
|
let fty = collect::ty_of_fn_decl(cx, convert, ty_of_arg, f.decl,
|
||||||
[], none).ty;
|
f.proto, [], none).ty;
|
||||||
|
|
||||||
write::ty_only_fixup(fcx, id, fty);
|
write::ty_only_fixup(fcx, id, fty);
|
||||||
|
|
||||||
// Unify the type of the function with the expected type before we
|
// Unify the type of the function with the expected type before we
|
||||||
|
@ -2041,6 +2056,9 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
||||||
unify(fcx, expr.span, expected, fty);
|
unify(fcx, expr.span, expected, fty);
|
||||||
|
|
||||||
check_fn(fcx.ccx, f, id, some(fcx));
|
check_fn(fcx.ccx, f, id, some(fcx));
|
||||||
|
if f.proto == ast::proto_block {
|
||||||
|
write::ty_only_fixup(fcx, id, expected);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ast::expr_block(b) {
|
ast::expr_block(b) {
|
||||||
// If this is an unchecked block, turn off purity-checking
|
// If this is an unchecked block, turn off purity-checking
|
||||||
|
@ -2301,7 +2319,8 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
|
||||||
// FIXME: These next three functions are largely ripped off from
|
// FIXME: These next three functions are largely ripped off from
|
||||||
// similar ones in collect::. Is there a better way to do this?
|
// similar ones in collect::. Is there a better way to do this?
|
||||||
fn ty_of_arg(ccx: @crate_ctxt, a: ast::arg) -> ty::arg {
|
fn ty_of_arg(ccx: @crate_ctxt, a: ast::arg) -> ty::arg {
|
||||||
ret {mode: a.mode, ty: ast_ty_to_ty_crate(ccx, a.ty)};
|
let ty = ast_ty_to_ty_crate(ccx, a.ty);
|
||||||
|
ret {mode: default_arg_mode_for_ty(ccx.tcx, a.mode, ty), ty: ty};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn ty_of_method(ccx: @crate_ctxt, m: @ast::method) -> ty::method {
|
fn ty_of_method(ccx: @crate_ctxt, m: @ast::method) -> ty::method {
|
||||||
|
|
|
@ -132,7 +132,7 @@ tag unop {
|
||||||
deref; not; neg;
|
deref; not; neg;
|
||||||
}
|
}
|
||||||
|
|
||||||
tag mode { by_ref; by_mut_ref; by_move; }
|
tag mode { by_ref; by_val; by_mut_ref; by_move; mode_infer; }
|
||||||
|
|
||||||
type stmt = spanned<stmt_>;
|
type stmt = spanned<stmt_>;
|
||||||
|
|
||||||
|
|
|
@ -180,9 +180,9 @@ fn is_constraint_arg(e: @expr) -> bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn eq_ty(a: @ty, b: @ty) -> bool { ret std::box::ptr_eq(a, b); }
|
fn eq_ty(&&a: @ty, &&b: @ty) -> bool { ret std::box::ptr_eq(a, b); }
|
||||||
|
|
||||||
fn hash_ty(t: @ty) -> uint { ret t.span.lo << 16u + t.span.hi; }
|
fn hash_ty(&&t: @ty) -> uint { ret t.span.lo << 16u + t.span.hi; }
|
||||||
|
|
||||||
fn block_from_expr(e: @expr) -> blk {
|
fn block_from_expr(e: @expr) -> blk {
|
||||||
let blk_ = checked_blk([], option::some::<@expr>(e), e.id);
|
let blk_ = checked_blk([], option::some::<@expr>(e), e.id);
|
||||||
|
|
|
@ -266,7 +266,7 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
|
||||||
recur: fn(@expr) -> @expr, exprs: [@expr]) -> [@expr] {
|
recur: fn(@expr) -> @expr, exprs: [@expr]) -> [@expr] {
|
||||||
alt elts_to_ell(cx, exprs) {
|
alt elts_to_ell(cx, exprs) {
|
||||||
{pre: pre, rep: repeat_me_maybe, post: post} {
|
{pre: pre, rep: repeat_me_maybe, post: post} {
|
||||||
let res = vec::map(recur, pre);
|
let res = vec::map_imm(recur, pre);
|
||||||
alt repeat_me_maybe {
|
alt repeat_me_maybe {
|
||||||
none. { }
|
none. { }
|
||||||
some(repeat_me) {
|
some(repeat_me) {
|
||||||
|
@ -315,7 +315,7 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mutable [uint],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
res += vec::map(recur, post);
|
res += vec::map_imm(recur, post);
|
||||||
ret res;
|
ret res;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -110,7 +110,7 @@ fn fold_meta_item_(mi: @meta_item, fld: ast_fold) -> @meta_item {
|
||||||
meta_word(id) { meta_word(fld.fold_ident(id)) }
|
meta_word(id) { meta_word(fld.fold_ident(id)) }
|
||||||
meta_list(id, mis) {
|
meta_list(id, mis) {
|
||||||
let fold_meta_item = bind fold_meta_item_(_, fld);
|
let fold_meta_item = bind fold_meta_item_(_, fld);
|
||||||
meta_list(id, vec::map(fold_meta_item, mis))
|
meta_list(id, vec::map_imm(fold_meta_item, mis))
|
||||||
}
|
}
|
||||||
meta_name_value(id, s) {
|
meta_name_value(id, s) {
|
||||||
meta_name_value(fld.fold_ident(id), s)
|
meta_name_value(fld.fold_ident(id), s)
|
||||||
|
@ -153,10 +153,10 @@ fn noop_fold_crate(c: crate_, fld: ast_fold) -> crate_ {
|
||||||
let fold_meta_item = bind fold_meta_item_(_, fld);
|
let fold_meta_item = bind fold_meta_item_(_, fld);
|
||||||
let fold_attribute = bind fold_attribute_(_, fold_meta_item);
|
let fold_attribute = bind fold_attribute_(_, fold_meta_item);
|
||||||
|
|
||||||
ret {directives: vec::map(fld.fold_crate_directive, c.directives),
|
ret {directives: vec::map_imm(fld.fold_crate_directive, c.directives),
|
||||||
module: fld.fold_mod(c.module),
|
module: fld.fold_mod(c.module),
|
||||||
attrs: vec::map(fold_attribute, c.attrs),
|
attrs: vec::map(fold_attribute, c.attrs),
|
||||||
config: vec::map(fold_meta_item, c.config)};
|
config: vec::map_imm(fold_meta_item, c.config)};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn noop_fold_crate_directive(cd: crate_directive_, fld: ast_fold) ->
|
fn noop_fold_crate_directive(cd: crate_directive_, fld: ast_fold) ->
|
||||||
|
@ -167,7 +167,7 @@ fn noop_fold_crate_directive(cd: crate_directive_, fld: ast_fold) ->
|
||||||
}
|
}
|
||||||
cdir_dir_mod(id, fname, cds, attrs) {
|
cdir_dir_mod(id, fname, cds, attrs) {
|
||||||
cdir_dir_mod(fld.fold_ident(id), fname,
|
cdir_dir_mod(fld.fold_ident(id), fname,
|
||||||
vec::map(fld.fold_crate_directive, cds), attrs)
|
vec::map_imm(fld.fold_crate_directive, cds), attrs)
|
||||||
}
|
}
|
||||||
cdir_view_item(vi) { cdir_view_item(fld.fold_view_item(vi)) }
|
cdir_view_item(vi) { cdir_view_item(fld.fold_view_item(vi)) }
|
||||||
cdir_syntax(_) { cd }
|
cdir_syntax(_) { cd }
|
||||||
|
@ -198,8 +198,8 @@ fn noop_fold_native_item(ni: @native_item, fld: ast_fold) -> @native_item {
|
||||||
il: fdec.il,
|
il: fdec.il,
|
||||||
cf: fdec.cf,
|
cf: fdec.cf,
|
||||||
constraints:
|
constraints:
|
||||||
vec::map(fld.fold_constr,
|
vec::map_imm(fld.fold_constr,
|
||||||
fdec.constraints)}, typms)
|
fdec.constraints)}, typms)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
id: ni.id,
|
id: ni.id,
|
||||||
|
@ -237,8 +237,8 @@ fn noop_fold_item_underscore(i: item_, fld: ast_fold) -> item_ {
|
||||||
}
|
}
|
||||||
item_obj(o, typms, d) {
|
item_obj(o, typms, d) {
|
||||||
item_obj({fields: vec::map(fold_obj_field, o.fields),
|
item_obj({fields: vec::map(fold_obj_field, o.fields),
|
||||||
methods: vec::map(fld.fold_method, o.methods)}, typms,
|
methods: vec::map_imm(fld.fold_method, o.methods)},
|
||||||
d)
|
typms, d)
|
||||||
}
|
}
|
||||||
item_res(dtor, did, typms, cid) {
|
item_res(dtor, did, typms, cid) {
|
||||||
item_res(fld.fold_fn(dtor), did, typms, cid)
|
item_res(fld.fold_fn(dtor), did, typms, cid)
|
||||||
|
@ -252,8 +252,8 @@ fn noop_fold_method(m: method_, fld: ast_fold) -> method_ {
|
||||||
|
|
||||||
|
|
||||||
fn noop_fold_block(b: blk_, fld: ast_fold) -> blk_ {
|
fn noop_fold_block(b: blk_, fld: ast_fold) -> blk_ {
|
||||||
ret {stmts: vec::map(fld.fold_stmt, b.stmts),
|
ret {stmts: vec::map_imm(fld.fold_stmt, b.stmts),
|
||||||
expr: option::map(fld.fold_expr, b.expr),
|
expr: option::map_imm(fld.fold_expr, b.expr),
|
||||||
id: b.id,
|
id: b.id,
|
||||||
rules: b.rules};
|
rules: b.rules};
|
||||||
}
|
}
|
||||||
|
@ -269,8 +269,8 @@ fn noop_fold_stmt(s: stmt_, fld: ast_fold) -> stmt_ {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn noop_fold_arm(a: arm, fld: ast_fold) -> arm {
|
fn noop_fold_arm(a: arm, fld: ast_fold) -> arm {
|
||||||
ret {pats: vec::map(fld.fold_pat, a.pats),
|
ret {pats: vec::map_imm(fld.fold_pat, a.pats),
|
||||||
guard: option::map(fld.fold_expr, a.guard),
|
guard: option::map_imm(fld.fold_expr, a.guard),
|
||||||
body: fld.fold_block(a.body)};
|
body: fld.fold_block(a.body)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +280,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
|
||||||
pat_bind(ident) { pat_bind(fld.fold_ident(ident)) }
|
pat_bind(ident) { pat_bind(fld.fold_ident(ident)) }
|
||||||
pat_lit(_) { p }
|
pat_lit(_) { p }
|
||||||
pat_tag(pth, pats) {
|
pat_tag(pth, pats) {
|
||||||
pat_tag(fld.fold_path(pth), vec::map(fld.fold_pat, pats))
|
pat_tag(fld.fold_path(pth), vec::map_imm(fld.fold_pat, pats))
|
||||||
}
|
}
|
||||||
pat_rec(fields, etc) {
|
pat_rec(fields, etc) {
|
||||||
let fs = [];
|
let fs = [];
|
||||||
|
@ -289,7 +289,7 @@ fn noop_fold_pat(p: pat_, fld: ast_fold) -> pat_ {
|
||||||
}
|
}
|
||||||
pat_rec(fs, etc)
|
pat_rec(fs, etc)
|
||||||
}
|
}
|
||||||
pat_tup(elts) { pat_tup(vec::map(fld.fold_pat, elts)) }
|
pat_tup(elts) { pat_tup(vec::map_imm(fld.fold_pat, elts)) }
|
||||||
pat_box(inner) { pat_box(fld.fold_pat(inner)) }
|
pat_box(inner) { pat_box(fld.fold_pat(inner)) }
|
||||||
pat_uniq(inner) { pat_uniq(fld.fold_pat(inner)) }
|
pat_uniq(inner) { pat_uniq(fld.fold_pat(inner)) }
|
||||||
pat_range(_, _) { p }
|
pat_range(_, _) { p }
|
||||||
|
@ -334,8 +334,8 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
|
||||||
option::some(vec::map(fold_anon_obj_field, v))
|
option::some(vec::map(fold_anon_obj_field, v))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: vec::map(fld.fold_method, ao.methods),
|
methods: vec::map_imm(fld.fold_method, ao.methods),
|
||||||
inner_obj: option::map(fld.fold_expr, ao.inner_obj)}
|
inner_obj: option::map_imm(fld.fold_expr, ao.inner_obj)}
|
||||||
}
|
}
|
||||||
let fold_anon_obj = bind fold_anon_obj_(_, fld);
|
let fold_anon_obj = bind fold_anon_obj_(_, fld);
|
||||||
|
|
||||||
|
@ -347,15 +347,15 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
|
||||||
}
|
}
|
||||||
expr_rec(fields, maybe_expr) {
|
expr_rec(fields, maybe_expr) {
|
||||||
expr_rec(vec::map(fold_field, fields),
|
expr_rec(vec::map(fold_field, fields),
|
||||||
option::map(fld.fold_expr, maybe_expr))
|
option::map_imm(fld.fold_expr, maybe_expr))
|
||||||
}
|
}
|
||||||
expr_tup(elts) { expr_tup(vec::map(fld.fold_expr, elts)) }
|
expr_tup(elts) { expr_tup(vec::map_imm(fld.fold_expr, elts)) }
|
||||||
expr_call(f, args) {
|
expr_call(f, args) {
|
||||||
expr_call(fld.fold_expr(f), fld.map_exprs(fld.fold_expr, args))
|
expr_call(fld.fold_expr(f), fld.map_exprs(fld.fold_expr, args))
|
||||||
}
|
}
|
||||||
expr_self_method(id) { expr_self_method(fld.fold_ident(id)) }
|
expr_self_method(id) { expr_self_method(fld.fold_ident(id)) }
|
||||||
expr_bind(f, args) {
|
expr_bind(f, args) {
|
||||||
let opt_map_se = bind option::map(fld.fold_expr, _);
|
let opt_map_se = bind option::map_imm(fld.fold_expr, _);
|
||||||
expr_bind(fld.fold_expr(f), vec::map(opt_map_se, args))
|
expr_bind(fld.fold_expr(f), vec::map(opt_map_se, args))
|
||||||
}
|
}
|
||||||
expr_binary(binop, lhs, rhs) {
|
expr_binary(binop, lhs, rhs) {
|
||||||
|
@ -366,7 +366,7 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
|
||||||
expr_cast(expr, ty) { expr_cast(fld.fold_expr(expr), ty) }
|
expr_cast(expr, ty) { expr_cast(fld.fold_expr(expr), ty) }
|
||||||
expr_if(cond, tr, fl) {
|
expr_if(cond, tr, fl) {
|
||||||
expr_if(fld.fold_expr(cond), fld.fold_block(tr),
|
expr_if(fld.fold_expr(cond), fld.fold_block(tr),
|
||||||
option::map(fld.fold_expr, fl))
|
option::map_imm(fld.fold_expr, fl))
|
||||||
}
|
}
|
||||||
expr_ternary(cond, tr, fl) {
|
expr_ternary(cond, tr, fl) {
|
||||||
expr_ternary(fld.fold_expr(cond), fld.fold_expr(tr),
|
expr_ternary(fld.fold_expr(cond), fld.fold_expr(tr),
|
||||||
|
@ -411,18 +411,18 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
|
||||||
expr_index(fld.fold_expr(el), fld.fold_expr(er))
|
expr_index(fld.fold_expr(el), fld.fold_expr(er))
|
||||||
}
|
}
|
||||||
expr_path(pth) { expr_path(fld.fold_path(pth)) }
|
expr_path(pth) { expr_path(fld.fold_path(pth)) }
|
||||||
expr_fail(e) { expr_fail(option::map(fld.fold_expr, e)) }
|
expr_fail(e) { expr_fail(option::map_imm(fld.fold_expr, e)) }
|
||||||
expr_break. { e }
|
expr_break. { e }
|
||||||
expr_cont. { e }
|
expr_cont. { e }
|
||||||
expr_ret(e) { expr_ret(option::map(fld.fold_expr, e)) }
|
expr_ret(e) { expr_ret(option::map_imm(fld.fold_expr, e)) }
|
||||||
expr_put(e) { expr_put(option::map(fld.fold_expr, e)) }
|
expr_put(e) { expr_put(option::map_imm(fld.fold_expr, e)) }
|
||||||
expr_be(e) { expr_be(fld.fold_expr(e)) }
|
expr_be(e) { expr_be(fld.fold_expr(e)) }
|
||||||
expr_log(lv, e) { expr_log(lv, fld.fold_expr(e)) }
|
expr_log(lv, e) { expr_log(lv, fld.fold_expr(e)) }
|
||||||
expr_assert(e) { expr_assert(fld.fold_expr(e)) }
|
expr_assert(e) { expr_assert(fld.fold_expr(e)) }
|
||||||
expr_check(m, e) { expr_check(m, fld.fold_expr(e)) }
|
expr_check(m, e) { expr_check(m, fld.fold_expr(e)) }
|
||||||
expr_if_check(cond, tr, fl) {
|
expr_if_check(cond, tr, fl) {
|
||||||
expr_if_check(fld.fold_expr(cond), fld.fold_block(tr),
|
expr_if_check(fld.fold_expr(cond), fld.fold_block(tr),
|
||||||
option::map(fld.fold_expr, fl))
|
option::map_imm(fld.fold_expr, fl))
|
||||||
}
|
}
|
||||||
expr_anon_obj(ao) { expr_anon_obj(fold_anon_obj(ao)) }
|
expr_anon_obj(ao) { expr_anon_obj(fold_anon_obj(ao)) }
|
||||||
expr_mac(mac) { expr_mac(fold_mac(mac)) }
|
expr_mac(mac) { expr_mac(fold_mac(mac)) }
|
||||||
|
@ -448,22 +448,22 @@ fn noop_fold_fn(f: _fn, fld: ast_fold) -> _fn {
|
||||||
purity: f.decl.purity,
|
purity: f.decl.purity,
|
||||||
il: f.decl.il,
|
il: f.decl.il,
|
||||||
cf: f.decl.cf,
|
cf: f.decl.cf,
|
||||||
constraints: vec::map(fld.fold_constr, f.decl.constraints)},
|
constraints: vec::map_imm(fld.fold_constr, f.decl.constraints)},
|
||||||
proto: f.proto,
|
proto: f.proto,
|
||||||
body: fld.fold_block(f.body)};
|
body: fld.fold_block(f.body)};
|
||||||
}
|
}
|
||||||
|
|
||||||
// ...nor do modules
|
// ...nor do modules
|
||||||
fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod {
|
fn noop_fold_mod(m: _mod, fld: ast_fold) -> _mod {
|
||||||
ret {view_items: vec::map(fld.fold_view_item, m.view_items),
|
ret {view_items: vec::map_imm(fld.fold_view_item, m.view_items),
|
||||||
items: vec::map(fld.fold_item, m.items)};
|
items: vec::map_imm(fld.fold_item, m.items)};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn noop_fold_native_mod(nm: native_mod, fld: ast_fold) -> native_mod {
|
fn noop_fold_native_mod(nm: native_mod, fld: ast_fold) -> native_mod {
|
||||||
ret {native_name: nm.native_name,
|
ret {native_name: nm.native_name,
|
||||||
abi: nm.abi,
|
abi: nm.abi,
|
||||||
view_items: vec::map(fld.fold_view_item, nm.view_items),
|
view_items: vec::map_imm(fld.fold_view_item, nm.view_items),
|
||||||
items: vec::map(fld.fold_native_item, nm.items)}
|
items: vec::map_imm(fld.fold_native_item, nm.items)}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
|
fn noop_fold_variant(v: variant_, fld: ast_fold) -> variant_ {
|
||||||
|
@ -479,7 +479,7 @@ fn noop_fold_ident(i: ident, _fld: ast_fold) -> ident { ret i; }
|
||||||
fn noop_fold_path(p: path_, fld: ast_fold) -> path_ {
|
fn noop_fold_path(p: path_, fld: ast_fold) -> path_ {
|
||||||
ret {global: p.global,
|
ret {global: p.global,
|
||||||
idents: vec::map(fld.fold_ident, p.idents),
|
idents: vec::map(fld.fold_ident, p.idents),
|
||||||
types: vec::map(fld.fold_ty, p.types)};
|
types: vec::map_imm(fld.fold_ty, p.types)};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn noop_fold_local(l: local_, fld: ast_fold) -> local_ {
|
fn noop_fold_local(l: local_, fld: ast_fold) -> local_ {
|
||||||
|
@ -499,7 +499,7 @@ fn noop_fold_local(l: local_, fld: ast_fold) -> local_ {
|
||||||
/* temporarily eta-expand because of a compiler bug with using `fn<T>` as a
|
/* temporarily eta-expand because of a compiler bug with using `fn<T>` as a
|
||||||
value */
|
value */
|
||||||
fn noop_map_exprs(f: fn(@expr) -> @expr, es: [@expr]) -> [@expr] {
|
fn noop_map_exprs(f: fn(@expr) -> @expr, es: [@expr]) -> [@expr] {
|
||||||
ret vec::map(f, es);
|
ret vec::map_imm(f, es);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn noop_id(i: node_id) -> node_id { ret i; }
|
fn noop_id(i: node_id) -> node_id { ret i; }
|
||||||
|
|
|
@ -587,17 +587,11 @@ fn parse_ty(p: parser, colons_before_params: bool) -> @ast::ty {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_arg_mode(p: parser) -> ast::mode {
|
fn parse_arg_mode(p: parser) -> ast::mode {
|
||||||
if eat(p, token::BINOP(token::AND)) {
|
if eat(p, token::BINOP(token::AND)) { ast::by_mut_ref }
|
||||||
ret ast::by_mut_ref;
|
else if eat(p, token::BINOP(token::MINUS)) { ast::by_move }
|
||||||
} else if eat(p, token::BINOP(token::MINUS)) {
|
else if eat(p, token::ANDAND) { ast::by_ref }
|
||||||
ret ast::by_move;
|
else if eat(p, token::BINOP(token::PLUS)) { ast::by_val }
|
||||||
} else {
|
else { ast::mode_infer }
|
||||||
// FIXME Temporarily ignore these, to make it possible to implement
|
|
||||||
// them without breaking the stage0 build.
|
|
||||||
eat(p, token::ANDAND);
|
|
||||||
eat(p, token::BINOP(token::PLUS));
|
|
||||||
ret ast::by_ref;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_arg(p: parser) -> ast::arg {
|
fn parse_arg(p: parser) -> ast::arg {
|
||||||
|
@ -1890,7 +1884,8 @@ fn parse_item_res(p: parser, attrs: [ast::attribute]) -> @ast::item {
|
||||||
let dtor = parse_block_no_value(p);
|
let dtor = parse_block_no_value(p);
|
||||||
let decl =
|
let decl =
|
||||||
{inputs:
|
{inputs:
|
||||||
[{mode: ast::by_ref, ty: t, ident: arg_ident, id: p.get_id()}],
|
[{mode: ast::by_ref, ty: t, ident: arg_ident,
|
||||||
|
id: p.get_id()}],
|
||||||
output: @spanned(lo, lo, ast::ty_nil),
|
output: @spanned(lo, lo, ast::ty_nil),
|
||||||
purity: ast::impure_fn,
|
purity: ast::impure_fn,
|
||||||
il: ast::il_normal,
|
il: ast::il_normal,
|
||||||
|
|
|
@ -226,7 +226,7 @@ fn commasep_cmnt<IN>(s: ps, b: breaks, elts: [IN], op: fn(ps, IN),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn commasep_exprs(s: ps, b: breaks, exprs: [@ast::expr]) {
|
fn commasep_exprs(s: ps, b: breaks, exprs: [@ast::expr]) {
|
||||||
fn expr_span(expr: @ast::expr) -> codemap::span { ret expr.span; }
|
fn expr_span(&&expr: @ast::expr) -> codemap::span { ret expr.span; }
|
||||||
commasep_cmnt(s, b, exprs, print_expr, expr_span);
|
commasep_cmnt(s, b, exprs, print_expr, expr_span);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ fn print_native_mod(s: ps, nmod: ast::native_mod, attrs: [ast::attribute]) {
|
||||||
for item: @ast::native_item in nmod.items { print_native_item(s, item); }
|
for item: @ast::native_item in nmod.items { print_native_item(s, item); }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_type(s: ps, ty: @ast::ty) {
|
fn print_type(s: ps, &&ty: @ast::ty) {
|
||||||
maybe_print_comment(s, ty.span.lo);
|
maybe_print_comment(s, ty.span.lo);
|
||||||
ibox(s, 0u);
|
ibox(s, 0u);
|
||||||
alt ty.node {
|
alt ty.node {
|
||||||
|
@ -365,7 +365,7 @@ fn print_native_item(s: ps, item: @ast::native_item) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_item(s: ps, item: @ast::item) {
|
fn print_item(s: ps, &&item: @ast::item) {
|
||||||
hardbreak_if_not_bol(s);
|
hardbreak_if_not_bol(s);
|
||||||
maybe_print_comment(s, item.span.lo);
|
maybe_print_comment(s, item.span.lo);
|
||||||
print_outer_attributes(s, item.attrs);
|
print_outer_attributes(s, item.attrs);
|
||||||
|
@ -678,7 +678,7 @@ fn print_mac(s: ps, m: ast::mac) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_expr(s: ps, expr: @ast::expr) {
|
fn print_expr(s: ps, &&expr: @ast::expr) {
|
||||||
maybe_print_comment(s, expr.span.lo);
|
maybe_print_comment(s, expr.span.lo);
|
||||||
ibox(s, indent_unit);
|
ibox(s, indent_unit);
|
||||||
let ann_node = node_expr(s, expr);
|
let ann_node = node_expr(s, expr);
|
||||||
|
@ -1080,7 +1080,7 @@ fn print_path(s: ps, path: ast::path, colons_before_params: bool) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_pat(s: ps, pat: @ast::pat) {
|
fn print_pat(s: ps, &&pat: @ast::pat) {
|
||||||
maybe_print_comment(s, pat.span.lo);
|
maybe_print_comment(s, pat.span.lo);
|
||||||
let ann_node = node_pat(s, pat);
|
let ann_node = node_pat(s, pat);
|
||||||
s.ann.pre(ann_node);
|
s.ann.pre(ann_node);
|
||||||
|
@ -1145,7 +1145,7 @@ fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl, constrs: [@ast::constr]) {
|
||||||
popen(s);
|
popen(s);
|
||||||
fn print_arg(s: ps, x: ast::arg) {
|
fn print_arg(s: ps, x: ast::arg) {
|
||||||
ibox(s, indent_unit);
|
ibox(s, indent_unit);
|
||||||
print_alias(s, x.mode);
|
print_arg_mode(s, x.mode);
|
||||||
word_space(s, x.ident + ":");
|
word_space(s, x.ident + ":");
|
||||||
print_type(s, x.ty);
|
print_type(s, x.ty);
|
||||||
end(s);
|
end(s);
|
||||||
|
@ -1174,7 +1174,7 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl) {
|
||||||
word(s.s, "|");
|
word(s.s, "|");
|
||||||
fn print_arg(s: ps, x: ast::arg) {
|
fn print_arg(s: ps, x: ast::arg) {
|
||||||
ibox(s, indent_unit);
|
ibox(s, indent_unit);
|
||||||
print_alias(s, x.mode);
|
print_arg_mode(s, x.mode);
|
||||||
word(s.s, x.ident);
|
word(s.s, x.ident);
|
||||||
end(s);
|
end(s);
|
||||||
}
|
}
|
||||||
|
@ -1183,11 +1183,13 @@ fn print_fn_block_args(s: ps, decl: ast::fn_decl) {
|
||||||
maybe_print_comment(s, decl.output.span.lo);
|
maybe_print_comment(s, decl.output.span.lo);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_alias(s: ps, m: ast::mode) {
|
fn print_arg_mode(s: ps, m: ast::mode) {
|
||||||
alt m {
|
alt m {
|
||||||
ast::by_mut_ref. { word(s.s, "&"); }
|
ast::by_mut_ref. { word(s.s, "&"); }
|
||||||
ast::by_move. { word(s.s, "-"); }
|
ast::by_move. { word(s.s, "-"); }
|
||||||
ast::by_ref. { }
|
ast::by_ref. { word(s.s, "&&"); }
|
||||||
|
ast::by_val. { word(s.s, "+"); }
|
||||||
|
ast::mode_infer. {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1211,7 +1213,7 @@ fn print_type_params(s: ps, params: [ast::ty_param]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_meta_item(s: ps, item: @ast::meta_item) {
|
fn print_meta_item(s: ps, &&item: @ast::meta_item) {
|
||||||
ibox(s, indent_unit);
|
ibox(s, indent_unit);
|
||||||
alt item.node {
|
alt item.node {
|
||||||
ast::meta_word(name) { word(s.s, name); }
|
ast::meta_word(name) { word(s.s, name); }
|
||||||
|
@ -1351,7 +1353,7 @@ fn print_ty_fn(s: ps, proto: ast::proto, id: option::t<ast::ident>,
|
||||||
zerobreak(s.s);
|
zerobreak(s.s);
|
||||||
popen(s);
|
popen(s);
|
||||||
fn print_arg(s: ps, input: ast::ty_arg) {
|
fn print_arg(s: ps, input: ast::ty_arg) {
|
||||||
print_alias(s, input.node.mode);
|
print_arg_mode(s, input.node.mode);
|
||||||
print_type(s, input.node.ty);
|
print_type(s, input.node.ty);
|
||||||
}
|
}
|
||||||
commasep(s, inconsistent, inputs, print_arg);
|
commasep(s, inconsistent, inputs, print_arg);
|
||||||
|
@ -1418,7 +1420,7 @@ fn in_cbox(s: ps) -> bool {
|
||||||
ret s.boxes[len - 1u] == pp::consistent;
|
ret s.boxes[len - 1u] == pp::consistent;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_literal(s: ps, lit: @ast::lit) {
|
fn print_literal(s: ps, &&lit: @ast::lit) {
|
||||||
maybe_print_comment(s, lit.span.lo);
|
maybe_print_comment(s, lit.span.lo);
|
||||||
alt next_lit(s) {
|
alt next_lit(s) {
|
||||||
some(lt) {
|
some(lt) {
|
||||||
|
@ -1596,7 +1598,7 @@ fn constr_arg_to_str<T>(f: fn(T) -> str, c: ast::constr_arg_general_<T>) ->
|
||||||
// needed b/c constr_args_to_str needs
|
// needed b/c constr_args_to_str needs
|
||||||
// something that takes an alias
|
// something that takes an alias
|
||||||
// (argh)
|
// (argh)
|
||||||
fn uint_to_str(i: uint) -> str { ret uint::str(i); }
|
fn uint_to_str(&&i: uint) -> str { ret uint::str(i); }
|
||||||
|
|
||||||
fn ast_ty_fn_constr_to_str(c: @ast::constr) -> str {
|
fn ast_ty_fn_constr_to_str(c: @ast::constr) -> str {
|
||||||
ret path_to_str(c.node.path) +
|
ret path_to_str(c.node.path) +
|
||||||
|
@ -1614,7 +1616,7 @@ fn ast_ty_fn_constrs_str(constrs: [@ast::constr]) -> str {
|
||||||
ret s;
|
ret s;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fn_arg_idx_to_str(decl: ast::fn_decl, idx: uint) -> str {
|
fn fn_arg_idx_to_str(decl: ast::fn_decl, &&idx: uint) -> str {
|
||||||
decl.inputs[idx].ident
|
decl.inputs[idx].ident
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -377,62 +377,62 @@ fn default_simple_visitor() -> simple_visitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
|
fn mk_simple_visitor(v: simple_visitor) -> vt<()> {
|
||||||
fn v_mod(f: fn(_mod, span), m: _mod, sp: span, e: (), v: vt<()>) {
|
fn v_mod(f: fn(_mod, span), m: _mod, sp: span, &&e: (), v: vt<()>) {
|
||||||
f(m, sp);
|
f(m, sp);
|
||||||
visit_mod(m, sp, e, v);
|
visit_mod(m, sp, e, v);
|
||||||
}
|
}
|
||||||
fn v_view_item(f: fn(@view_item), vi: @view_item, e: (), v: vt<()>) {
|
fn v_view_item(f: fn(@view_item), vi: @view_item, &&e: (), v: vt<()>) {
|
||||||
f(vi);
|
f(vi);
|
||||||
visit_view_item(vi, e, v);
|
visit_view_item(vi, e, v);
|
||||||
}
|
}
|
||||||
fn v_native_item(f: fn(@native_item), ni: @native_item, e: (),
|
fn v_native_item(f: fn(@native_item), ni: @native_item, &&e: (),
|
||||||
v: vt<()>) {
|
v: vt<()>) {
|
||||||
f(ni);
|
f(ni);
|
||||||
visit_native_item(ni, e, v);
|
visit_native_item(ni, e, v);
|
||||||
}
|
}
|
||||||
fn v_item(f: fn(@item), i: @item, e: (), v: vt<()>) {
|
fn v_item(f: fn(@item), i: @item, &&e: (), v: vt<()>) {
|
||||||
f(i);
|
f(i);
|
||||||
visit_item(i, e, v);
|
visit_item(i, e, v);
|
||||||
}
|
}
|
||||||
fn v_local(f: fn(@local), l: @local, e: (), v: vt<()>) {
|
fn v_local(f: fn(@local), l: @local, &&e: (), v: vt<()>) {
|
||||||
f(l);
|
f(l);
|
||||||
visit_local(l, e, v);
|
visit_local(l, e, v);
|
||||||
}
|
}
|
||||||
fn v_block(f: fn(ast::blk), bl: ast::blk, e: (), v: vt<()>) {
|
fn v_block(f: fn(ast::blk), bl: ast::blk, &&e: (), v: vt<()>) {
|
||||||
f(bl);
|
f(bl);
|
||||||
visit_block(bl, e, v);
|
visit_block(bl, e, v);
|
||||||
}
|
}
|
||||||
fn v_stmt(f: fn(@stmt), st: @stmt, e: (), v: vt<()>) {
|
fn v_stmt(f: fn(@stmt), st: @stmt, &&e: (), v: vt<()>) {
|
||||||
f(st);
|
f(st);
|
||||||
visit_stmt(st, e, v);
|
visit_stmt(st, e, v);
|
||||||
}
|
}
|
||||||
fn v_arm(f: fn(arm), a: arm, e: (), v: vt<()>) {
|
fn v_arm(f: fn(arm), a: arm, &&e: (), v: vt<()>) {
|
||||||
f(a);
|
f(a);
|
||||||
visit_arm(a, e, v);
|
visit_arm(a, e, v);
|
||||||
}
|
}
|
||||||
fn v_pat(f: fn(@pat), p: @pat, e: (), v: vt<()>) {
|
fn v_pat(f: fn(@pat), p: @pat, &&e: (), v: vt<()>) {
|
||||||
f(p);
|
f(p);
|
||||||
visit_pat(p, e, v);
|
visit_pat(p, e, v);
|
||||||
}
|
}
|
||||||
fn v_decl(f: fn(@decl), d: @decl, e: (), v: vt<()>) {
|
fn v_decl(f: fn(@decl), d: @decl, &&e: (), v: vt<()>) {
|
||||||
f(d);
|
f(d);
|
||||||
visit_decl(d, e, v);
|
visit_decl(d, e, v);
|
||||||
}
|
}
|
||||||
fn v_expr(f: fn(@expr), ex: @expr, e: (), v: vt<()>) {
|
fn v_expr(f: fn(@expr), ex: @expr, &&e: (), v: vt<()>) {
|
||||||
f(ex);
|
f(ex);
|
||||||
visit_expr(ex, e, v);
|
visit_expr(ex, e, v);
|
||||||
}
|
}
|
||||||
fn v_ty(f: fn(@ty), ty: @ty, e: (), v: vt<()>) {
|
fn v_ty(f: fn(@ty), ty: @ty, &&e: (), v: vt<()>) {
|
||||||
f(ty);
|
f(ty);
|
||||||
visit_ty(ty, e, v);
|
visit_ty(ty, e, v);
|
||||||
}
|
}
|
||||||
fn v_constr(f: fn(path, span, node_id), pt: path, sp: span, id: node_id,
|
fn v_constr(f: fn(path, span, node_id), pt: path, sp: span, id: node_id,
|
||||||
e: (), v: vt<()>) {
|
&&e: (), v: vt<()>) {
|
||||||
f(pt, sp, id);
|
f(pt, sp, id);
|
||||||
visit_constr(pt, sp, id, e, v);
|
visit_constr(pt, sp, id, e, v);
|
||||||
}
|
}
|
||||||
fn v_fn(f: fn(_fn, [ty_param], span, fn_ident, node_id), ff: _fn,
|
fn v_fn(f: fn(_fn, [ty_param], span, fn_ident, node_id), ff: _fn,
|
||||||
tps: [ty_param], sp: span, ident: fn_ident, id: node_id, e: (),
|
tps: [ty_param], sp: span, ident: fn_ident, id: node_id, &&e: (),
|
||||||
v: vt<()>) {
|
v: vt<()>) {
|
||||||
f(ff, tps, sp, ident, id);
|
f(ff, tps, sp, ident, id);
|
||||||
visit_fn(ff, tps, sp, ident, id, e, v);
|
visit_fn(ff, tps, sp, ident, id, e, v);
|
||||||
|
|
|
@ -13,9 +13,11 @@ import metadata::csearch;
|
||||||
|
|
||||||
fn mode_str(m: ty::mode) -> str {
|
fn mode_str(m: ty::mode) -> str {
|
||||||
alt m {
|
alt m {
|
||||||
ast::by_ref. { "" }
|
ast::by_ref. { "&&" }
|
||||||
|
ast::by_val. { "+" }
|
||||||
ast::by_mut_ref. { "&" }
|
ast::by_mut_ref. { "&" }
|
||||||
ast::by_move. { "-" }
|
ast::by_move. { "-" }
|
||||||
|
_ { "" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -175,14 +175,11 @@ fn stdin() -> reader {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn file_reader(path: str) -> reader {
|
fn file_reader(path: str) -> reader {
|
||||||
let f =
|
let f = str::as_buf(path, {|pathbuf|
|
||||||
str::as_buf(path,
|
str::as_buf("r", {|modebuf|
|
||||||
{|pathbuf|
|
os::libc::fopen(pathbuf, modebuf)
|
||||||
str::as_buf("r",
|
})
|
||||||
{|modebuf|
|
});
|
||||||
os::libc::fopen(pathbuf, modebuf)
|
|
||||||
})
|
|
||||||
});
|
|
||||||
if f as uint == 0u { log_err "error opening " + path; fail; }
|
if f as uint == 0u { log_err "error opening " + path; fail; }
|
||||||
ret new_reader(FILE_buf_reader(f, option::some(@FILE_res(f))));
|
ret new_reader(FILE_buf_reader(f, option::some(@FILE_res(f))));
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,7 +49,7 @@ fn has<@T>(ls_: list<T>, elt: T) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn length<@T>(ls: list<T>) -> uint {
|
fn length<@T>(ls: list<T>) -> uint {
|
||||||
fn count<T>(_t: T, u: uint) -> uint { ret u + 1u; }
|
fn count<T>(_t: T, &&u: uint) -> uint { ret u + 1u; }
|
||||||
ret foldl(ls, 0u, count);
|
ret foldl(ls, 0u, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -199,14 +199,14 @@ fn new_str_hash<@V>() -> hashmap<str, V> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_int_hash<@V>() -> hashmap<int, V> {
|
fn new_int_hash<@V>() -> hashmap<int, V> {
|
||||||
fn hash_int(x: int) -> uint { ret x as uint; }
|
fn hash_int(&&x: int) -> uint { ret x as uint; }
|
||||||
fn eq_int(a: int, b: int) -> bool { ret a == b; }
|
fn eq_int(&&a: int, &&b: int) -> bool { ret a == b; }
|
||||||
ret mk_hashmap(hash_int, eq_int);
|
ret mk_hashmap(hash_int, eq_int);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_uint_hash<@V>() -> hashmap<uint, V> {
|
fn new_uint_hash<@V>() -> hashmap<uint, V> {
|
||||||
fn hash_uint(x: uint) -> uint { ret x; }
|
fn hash_uint(&&x: uint) -> uint { ret x; }
|
||||||
fn eq_uint(a: uint, b: uint) -> bool { ret a == b; }
|
fn eq_uint(&&a: uint, &&b: uint) -> bool { ret a == b; }
|
||||||
ret mk_hashmap(hash_uint, eq_uint);
|
ret mk_hashmap(hash_uint, eq_uint);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,11 @@ fn get<@T>(opt: t<T>) -> &T {
|
||||||
fn map<@T, @U>(f: block(T) -> U, opt: t<T>) -> t<U> {
|
fn map<@T, @U>(f: block(T) -> U, opt: t<T>) -> t<U> {
|
||||||
alt opt { some(x) { some(f(x)) } none. { none } }
|
alt opt { some(x) { some(f(x)) } none. { none } }
|
||||||
}
|
}
|
||||||
|
// FIXME This is needed to make working with by-value functions a bit less
|
||||||
|
// painful. We should come up with a better solution.
|
||||||
|
fn map_imm<@T, @U>(f: block(+T) -> U, opt: t<T>) -> t<U> {
|
||||||
|
alt opt { some(x) { some(f(x)) } none. { none } }
|
||||||
|
}
|
||||||
|
|
||||||
fn is_none<@T>(opt: t<T>) -> bool {
|
fn is_none<@T>(opt: t<T>) -> bool {
|
||||||
alt opt { none. { true } some(_) { false } }
|
alt opt { none. { true } some(_) { false } }
|
||||||
|
|
|
@ -191,6 +191,17 @@ fn map<@T, @U>(f: block(T) -> U, v: [mutable? T]) -> [U] {
|
||||||
}
|
}
|
||||||
ret result;
|
ret result;
|
||||||
}
|
}
|
||||||
|
// FIXME This is needed to make working with by-value functions a bit less
|
||||||
|
// painful. We should come up with a better solution.
|
||||||
|
fn map_imm<@T, @U>(f: block(+T) -> U, v: [mutable? T]) -> [U] {
|
||||||
|
let result = [];
|
||||||
|
reserve(result, len(v));
|
||||||
|
for elem: T in v {
|
||||||
|
let elem2 = elem; // satisfies alias checker
|
||||||
|
result += [f(elem2)];
|
||||||
|
}
|
||||||
|
ret result;
|
||||||
|
}
|
||||||
|
|
||||||
fn map2<@T, @U, @V>(f: block(T, U) -> V, v0: [T], v1: [U]) -> [V] {
|
fn map2<@T, @U, @V>(f: block(T, U) -> V, v0: [T], v1: [U]) -> [V] {
|
||||||
let v0_len = len::<T>(v0);
|
let v0_len = len::<T>(v0);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue