Skip to content

Commit f9fbd86

Browse files
committed
Parse and typecheck by-value and by-ref arg specs
Add sprinkle && throughout the compiler to make it typecheck again. Issue #1008
1 parent 4709038 commit f9fbd86

32 files changed

+230
-197
lines changed

src/comp/front/attr.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ fn get_attr_name(attr: ast::attribute) -> ast::ident {
5757
fn find_meta_items_by_name(metas: [@ast::meta_item], name: ast::ident) ->
5858
[@ast::meta_item] {
5959
let filter =
60-
bind fn (m: @ast::meta_item, name: ast::ident) ->
60+
bind fn (&&m: @ast::meta_item, name: ast::ident) ->
6161
option::t<@ast::meta_item> {
6262
if get_meta_item_name(m) == name {
6363
option::some(m)
@@ -134,7 +134,7 @@ fn contains_name(metas: [@ast::meta_item], name: ast::ident) -> bool {
134134

135135
// FIXME: This needs to sort by meta_item variant in addition to the item name
136136
fn sort_meta_items(items: [@ast::meta_item]) -> [@ast::meta_item] {
137-
fn lteq(ma: @ast::meta_item, mb: @ast::meta_item) -> bool {
137+
fn lteq(&&ma: @ast::meta_item, &&mb: @ast::meta_item) -> bool {
138138
fn key(m: @ast::meta_item) -> ast::ident {
139139
alt m.node {
140140
ast::meta_word(name) { name }
@@ -160,7 +160,7 @@ fn remove_meta_items_by_name(items: [@ast::meta_item], name: str) ->
160160
[@ast::meta_item] {
161161

162162
let filter =
163-
bind fn (item: @ast::meta_item, name: str) ->
163+
bind fn (&&item: @ast::meta_item, name: str) ->
164164
option::t<@ast::meta_item> {
165165
if get_meta_item_name(item) != name {
166166
option::some(item)

src/comp/front/config.rs

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ fn strip_unconfigured_items(crate: @ast::crate) -> @ast::crate {
2020
ret res;
2121
}
2222

23-
fn filter_item(cfg: ast::crate_cfg, item: @ast::item) ->
23+
fn filter_item(cfg: ast::crate_cfg, &&item: @ast::item) ->
2424
option::t<@ast::item> {
2525
if item_in_cfg(cfg, item) { option::some(item) } else { option::none }
2626
}
@@ -29,11 +29,11 @@ fn fold_mod(cfg: ast::crate_cfg, m: ast::_mod, fld: fold::ast_fold) ->
2929
ast::_mod {
3030
let filter = bind filter_item(cfg, _);
3131
let filtered_items = vec::filter_map(filter, m.items);
32-
ret {view_items: vec::map(fld.fold_view_item, m.view_items),
33-
items: vec::map(fld.fold_item, filtered_items)};
32+
ret {view_items: vec::map_imm(fld.fold_view_item, m.view_items),
33+
items: vec::map_imm(fld.fold_item, filtered_items)};
3434
}
3535

36-
fn filter_native_item(cfg: ast::crate_cfg, item: @ast::native_item) ->
36+
fn filter_native_item(cfg: ast::crate_cfg, &&item: @ast::native_item) ->
3737
option::t<@ast::native_item> {
3838
if native_item_in_cfg(cfg, item) {
3939
option::some(item)
@@ -46,11 +46,11 @@ fn fold_native_mod(cfg: ast::crate_cfg, nm: ast::native_mod,
4646
let filtered_items = vec::filter_map(filter, nm.items);
4747
ret {native_name: nm.native_name,
4848
abi: nm.abi,
49-
view_items: vec::map(fld.fold_view_item, nm.view_items),
49+
view_items: vec::map_imm(fld.fold_view_item, nm.view_items),
5050
items: filtered_items};
5151
}
5252

53-
fn filter_stmt(cfg: ast::crate_cfg, stmt: @ast::stmt) ->
53+
fn filter_stmt(cfg: ast::crate_cfg, &&stmt: @ast::stmt) ->
5454
option::t<@ast::stmt> {
5555
alt stmt.node {
5656
ast::stmt_decl(decl, _) {
@@ -71,8 +71,8 @@ fn fold_block(cfg: ast::crate_cfg, b: ast::blk_, fld: fold::ast_fold) ->
7171
ast::blk_ {
7272
let filter = bind filter_stmt(cfg, _);
7373
let filtered_stmts = vec::filter_map(filter, b.stmts);
74-
ret {stmts: vec::map(fld.fold_stmt, filtered_stmts),
75-
expr: option::map(fld.fold_expr, b.expr),
74+
ret {stmts: vec::map_imm(fld.fold_stmt, filtered_stmts),
75+
expr: option::map_imm(fld.fold_expr, b.expr),
7676
id: b.id,
7777
rules: b.rules};
7878
}
@@ -97,21 +97,20 @@ fn in_cfg(cfg: ast::crate_cfg, attrs: [ast::attribute]) -> bool {
9797
// Pull the inner meta_items from the #[cfg(meta_item, ...)] attributes,
9898
// so we can match against them. This is the list of configurations for
9999
// which the item is valid
100-
let item_cfg_metas =
101-
{
102-
fn extract_metas(inner_items: [@ast::meta_item],
103-
cfg_item: @ast::meta_item) -> [@ast::meta_item] {
104-
alt cfg_item.node {
105-
ast::meta_list(name, items) {
106-
assert (name == "cfg");
107-
inner_items + items
108-
}
109-
_ { inner_items }
110-
}
100+
let item_cfg_metas = {
101+
fn extract_metas(inner_items: [@ast::meta_item],
102+
&&cfg_item: @ast::meta_item) -> [@ast::meta_item] {
103+
alt cfg_item.node {
104+
ast::meta_list(name, items) {
105+
assert (name == "cfg");
106+
inner_items + items
107+
}
108+
_ { inner_items }
111109
}
112-
let cfg_metas = attr::attr_metas(item_cfg_attrs);
113-
vec::foldl(extract_metas, [], cfg_metas)
114-
};
110+
}
111+
let cfg_metas = attr::attr_metas(item_cfg_attrs);
112+
vec::foldl(extract_metas, [], cfg_metas)
113+
};
115114

116115
for cfg_mi: @ast::meta_item in item_cfg_metas {
117116
if attr::contains(cfg, cfg_mi) { ret true; }

src/comp/front/test.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ fn fold_mod(_cx: test_ctxt, m: ast::_mod, fld: fold::ast_fold) -> ast::_mod {
5656
// the one we're going to add. FIXME: This is sloppy. Instead we should
5757
// have some mechanism to indicate to the translation pass which function
5858
// we want to be main.
59-
fn nomain(item: @ast::item) -> option::t<@ast::item> {
59+
fn nomain(&&item: @ast::item) -> option::t<@ast::item> {
6060
alt item.node {
6161
ast::item_fn(f, _) {
6262
if item.ident == "main" {

src/comp/lib/llvm.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -909,9 +909,9 @@ obj type_names(type_names: std::map::hashmap<TypeRef, str>,
909909
fn mk_type_names() -> type_names {
910910
let nt = std::map::new_str_hash::<TypeRef>();
911911

912-
fn hash(t: TypeRef) -> uint { ret t as uint; }
912+
fn hash(&&t: TypeRef) -> uint { ret t as uint; }
913913

914-
fn eq(a: TypeRef, b: TypeRef) -> bool { ret a as uint == b as uint; }
914+
fn eq(&&a: TypeRef, &&b: TypeRef) -> bool { ret a as uint == b as uint; }
915915

916916
let hasher: std::map::hashfn<TypeRef> = hash;
917917
let eqer: std::map::eqfn<TypeRef> = eq;

src/comp/metadata/common.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ const tag_crate_dep: uint = 0x26u;
6565
const tag_items_data_item_inlineness: uint = 0x27u;
6666

6767
// djb's cdb hashes.
68-
fn hash_node_id(node_id: int) -> uint { ret 177573u ^ (node_id as uint); }
68+
fn hash_node_id(&&node_id: int) -> uint { ret 177573u ^ (node_id as uint); }
6969

7070
fn hash_path(s: str) -> uint {
7171
let h = 5381u;

src/comp/metadata/encoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -427,7 +427,7 @@ fn encode_index<T>(ebml_w: ebml::writer, buckets: [@[entry<T>]],
427427

428428
fn write_str(writer: io::writer, s: str) { writer.write_str(s); }
429429

430-
fn write_int(writer: io::writer, n: int) {
430+
fn write_int(writer: io::writer, &&n: int) {
431431
writer.write_be_uint(n as uint, 4u);
432432
}
433433

src/comp/metadata/tydecode.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -380,14 +380,13 @@ fn parse_ty_fn(st: @pstate, sd: str_def) ->
380380
assert (next(st) as char == '[');
381381
let inputs: [ty::arg] = [];
382382
while peek(st) as char != ']' {
383-
let mode = ast::by_ref;
384-
if peek(st) as char == '&' {
385-
mode = ast::by_mut_ref;
386-
st.pos += 1u;
387-
} else if peek(st) as char == '-' {
388-
mode = ast::by_move;
389-
st.pos += 1u;
390-
}
383+
let mode = alt peek(st) as char {
384+
'&' { ast::by_mut_ref }
385+
'-' { ast::by_move }
386+
'=' { ast::by_ref }
387+
'+' { ast::by_val }
388+
};
389+
st.pos += 1u;
391390
inputs += [{mode: mode, ty: parse_ty(st, sd)}];
392391
}
393392
st.pos += 1u; // eat the ']'

src/comp/metadata/tyencode.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ fn enc_ty_fn(w: io::writer, cx: @ctxt, args: [ty::arg], out: ty::t,
207207
alt arg.mode {
208208
by_mut_ref. { w.write_char('&'); }
209209
by_move. { w.write_char('-'); }
210-
by_ref. { }
210+
by_ref. { w.write_char('='); }
211+
by_val. { w.write_char('+'); }
211212
}
212213
enc_ty(w, cx, arg.ty);
213214
}

src/comp/middle/alias.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -251,10 +251,8 @@ fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [binding] {
251251
mutable ok: valid,
252252
mutable copied: alt arg_t.mode {
253253
ast::by_move. { copied }
254-
ast::by_ref. {
255-
i + 1u == by_ref ? not_allowed : not_copied
256-
}
257254
ast::by_mut_ref. { not_allowed }
255+
_ { i + 1u == by_ref ? not_allowed : not_copied }
258256
}}];
259257
i += 1u;
260258
}

src/comp/middle/ast_map.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ fn map_expr(cx: ctx, ex: @expr) {
7676
}
7777

7878
fn new_smallintmap_int_adapter<@V>() -> std::map::hashmap<int, V> {
79-
let key_idx = fn (key: int) -> uint { key as uint };
79+
let key_idx = fn (&&key: int) -> uint { key as uint };
8080
let idx_key = fn (idx: uint) -> int { idx as int };
8181
ret new_smallintmap_adapter(key_idx, idx_key);
8282
}

src/comp/middle/check_alt.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
1111
tcx.sess.abort_if_errors();
1212
}
1313

14-
fn check_expr(tcx: ty::ctxt, ex: @expr, s: (), v: visit::vt<()>) {
14+
fn check_expr(tcx: ty::ctxt, ex: @expr, &&s: (), v: visit::vt<()>) {
1515
visit::visit_expr(ex, s, v);
1616
alt ex.node { expr_alt(_, arms) { check_arms(tcx, arms); } _ { } }
1717
}
@@ -123,7 +123,7 @@ fn pattern_supersedes(tcx: ty::ctxt, a: @pat, b: @pat) -> bool {
123123
}
124124
}
125125

126-
fn check_local(tcx: ty::ctxt, loc: @local, s: (), v: visit::vt<()>) {
126+
fn check_local(tcx: ty::ctxt, loc: @local, &&s: (), v: visit::vt<()>) {
127127
visit::visit_local(loc, s, v);
128128
if is_refutable(tcx, loc.node.pat) {
129129
tcx.sess.span_err(loc.node.pat.span,

src/comp/middle/freevars.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,10 @@ fn collect_freevars(def_map: resolve::def_map, walker: fn(visit::vt<int>)) ->
2929
let seen = new_int_hash();
3030
let refs = @mutable [];
3131

32-
fn ignore_item(_i: @ast::item, _depth: int, _v: visit::vt<int>) { }
32+
fn ignore_item(_i: @ast::item, &&_depth: int, _v: visit::vt<int>) { }
3333

3434
let walk_expr =
35-
lambda (expr: @ast::expr, depth: int, v: visit::vt<int>) {
35+
lambda (expr: @ast::expr, &&depth: int, v: visit::vt<int>) {
3636
alt expr.node {
3737
ast::expr_fn(f) {
3838
if f.proto == ast::proto_block ||

src/comp/middle/mut.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ fn mk_err(cx: @ctx, span: syntax::codemap::span, msg: msg, name: str) {
131131
});
132132
}
133133

134-
fn visit_decl(cx: @ctx, d: @decl, e: (), v: visit::vt<()>) {
134+
fn visit_decl(cx: @ctx, d: @decl, &&e: (), v: visit::vt<()>) {
135135
visit::visit_decl(d, e, v);
136136
alt d.node {
137137
decl_local(locs) {
@@ -148,7 +148,7 @@ fn visit_decl(cx: @ctx, d: @decl, e: (), v: visit::vt<()>) {
148148
}
149149
}
150150

151-
fn visit_expr(cx: @ctx, ex: @expr, e: (), v: visit::vt<()>) {
151+
fn visit_expr(cx: @ctx, ex: @expr, &&e: (), v: visit::vt<()>) {
152152
alt ex.node {
153153
expr_call(f, args) { check_call(cx, f, args); }
154154
expr_swap(lhs, rhs) {
@@ -225,7 +225,7 @@ fn check_call(cx: @ctx, f: @expr, args: [@expr]) {
225225
alt arg_t.mode {
226226
by_mut_ref. { check_lval(cx, args[i], msg_mut_ref); }
227227
by_move. { check_lval(cx, args[i], msg_move_out); }
228-
by_ref. {}
228+
_ {}
229229
}
230230
i += 1u;
231231
}

src/comp/middle/resolve.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1239,7 +1239,7 @@ fn mie_span(mie: mod_index_entry) -> span {
12391239
};
12401240
}
12411241

1242-
fn check_item(e: @env, i: @ast::item, x: (), v: vt<()>) {
1242+
fn check_item(e: @env, i: @ast::item, &&x: (), v: vt<()>) {
12431243
fn typaram_names(tps: [ast::ty_param]) -> [ident] {
12441244
let x: [ast::ident] = [];
12451245
for tp: ast::ty_param in tps { x += [tp.ident]; }
@@ -1276,7 +1276,7 @@ fn check_pat(ch: checker, p: @ast::pat) {
12761276
}
12771277
}
12781278

1279-
fn check_arm(e: @env, a: ast::arm, x: (), v: vt<()>) {
1279+
fn check_arm(e: @env, a: ast::arm, &&x: (), v: vt<()>) {
12801280
visit::visit_arm(a, x, v);
12811281
let ch0 = checker(*e, "binding");
12821282
check_pat(ch0, a.pats[0]);
@@ -1306,7 +1306,7 @@ fn check_arm(e: @env, a: ast::arm, x: (), v: vt<()>) {
13061306
}
13071307
}
13081308

1309-
fn check_block(e: @env, b: ast::blk, x: (), v: vt<()>) {
1309+
fn check_block(e: @env, b: ast::blk, &&x: (), v: vt<()>) {
13101310
visit::visit_block(b, x, v);
13111311
let values = checker(*e, "value");
13121312
let types = checker(*e, "type");
@@ -1359,7 +1359,7 @@ fn check_fn(e: env, sp: span, f: ast::_fn) {
13591359
ensure_unique(e, sp, f.decl.inputs, arg_name, "argument");
13601360
}
13611361

1362-
fn check_expr(e: @env, ex: @ast::expr, x: (), v: vt<()>) {
1362+
fn check_expr(e: @env, ex: @ast::expr, &&x: (), v: vt<()>) {
13631363
alt ex.node {
13641364
ast::expr_rec(fields, _) {
13651365
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<()>) {
13701370
visit::visit_expr(ex, x, v);
13711371
}
13721372

1373-
fn check_ty(e: @env, ty: @ast::ty, x: (), v: vt<()>) {
1373+
fn check_ty(e: @env, ty: @ast::ty, &&x: (), v: vt<()>) {
13741374
alt ty.node {
13751375
ast::ty_rec(fields) {
13761376
fn field_name(f: ast::ty_field) -> ident { ret f.node.ident; }

src/comp/middle/trans.rs

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3699,7 +3699,7 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef,
36993699
// be inspected. It's important for the value
37003700
// to have type lldestty0 (the callee's expected type).
37013701
val = llvm::LLVMGetUndef(lldestty0);
3702-
} else if arg.mode == ast::by_ref {
3702+
} else if arg.mode == ast::by_ref || arg.mode == ast::by_val {
37033703
let copied = false;
37043704
if !lv.is_mem && type_is_immediate(ccx, e_ty) {
37053705
val = do_spill_noroot(bcx, val);
@@ -4439,9 +4439,9 @@ fn lval_to_dps(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
44394439
// latter group "immediates" and, in some circumstances when we know we have a
44404440
// pointer (or need one), perform load/store operations based on the
44414441
// immediate-ness of the type.
4442+
// FIXME simply call the version in ty.rs immediately
44424443
fn type_is_immediate(ccx: @crate_ctxt, t: ty::t) -> bool {
4443-
ret ty::type_is_scalar(ccx.tcx, t) || ty::type_is_boxed(ccx.tcx, t) ||
4444-
ty::type_is_unique_box(ccx.tcx, t) || ty::type_is_native(ccx.tcx, t);
4444+
ty::type_is_immediate(ccx.tcx, t)
44454445
}
44464446

44474447
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],
51445144
for aarg: ast::arg in args {
51455145
let arg_ty = arg_tys[arg_n].ty;
51465146
alt aarg.mode {
5147-
ast::by_ref. {
5147+
ast::by_move. {
5148+
add_clean(bcx, fcx.llargs.get(aarg.id), arg_ty);
5149+
}
5150+
ast::by_mut_ref. { }
5151+
_ {
51485152
let mutated =
51495153
!ignore_mut && fcx.lcx.ccx.mut_map.contains_key(aarg.id);
51505154

@@ -5160,10 +5164,6 @@ fn copy_args_to_allocas(fcx: @fn_ctxt, bcx: @block_ctxt, args: [ast::arg],
51605164
add_clean(bcx, alloc, arg_ty);
51615165
}
51625166
}
5163-
ast::by_move. {
5164-
add_clean(bcx, fcx.llargs.get(aarg.id), arg_ty);
5165-
}
5166-
_ { }
51675167
}
51685168
arg_n += 1u;
51695169
}
@@ -5790,7 +5790,7 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str,
57905790
}
57915791
fn convert_arg_to_i32(cx: @block_ctxt, v: ValueRef, t: ty::t,
57925792
mode: ty::mode) -> ValueRef {
5793-
if mode == ast::by_ref {
5793+
if mode == ast::by_ref || mode == ast::by_val {
57945794
if ty::type_is_integral(bcx_tcx(cx), t) {
57955795
// FIXME: would be nice to have a postcondition that says
57965796
// 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,
58455845
let i = arg_n;
58465846
for arg: ty::arg in args {
58475847
let llarg = llvm::LLVMGetParam(fcx.llfn, i);
5848-
if arg.mode == ast::by_ref {
5848+
if arg.mode == ast::by_ref || arg.mode == ast::by_val {
58495849
llarg = load_if_immediate(bcx, llarg, arg.ty);
58505850
}
58515851
assert (llarg as int != 0);

src/comp/middle/trans_objects.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ fn trans_obj(cx: @local_ctxt, sp: span, ob: ast::_obj, ctor_id: ast::node_id,
4141
// we're creating.
4242
let fn_args: [ast::arg] = [];
4343
for f: ast::obj_field in ob.fields {
44-
fn_args += [{mode: ast::by_ref, ty: f.ty, ident: f.ident, id: f.id}];
44+
fn_args += [{mode: ast::by_ref, ty: f.ty, ident: f.ident,
45+
id: f.id}];
4546
}
4647
let fcx = new_fn_ctxt(cx, sp, llctor_decl);
4748

@@ -397,7 +398,7 @@ tag vtbl_mthd {
397398
}
398399

399400
// Alphabetize ast::methods by ident. A helper for create_vtbl.
400-
fn ast_mthd_lteq(a: @ast::method, b: @ast::method) -> bool {
401+
fn ast_mthd_lteq(&&a: @ast::method, &&b: @ast::method) -> bool {
401402
ret str::lteq(a.node.ident, b.node.ident);
402403
}
403404

0 commit comments

Comments
 (0)