Skip to content

Commit 9fb3719

Browse files
committed
Rollback return-by-reference
It's proving too inflexible, so I'm ripping out the extra complexity in the hope that regions will, at some point, provide something similar. Closes #918
1 parent acbc4aa commit 9fb3719

23 files changed

+50
-370
lines changed

src/comp/metadata/tydecode.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,6 @@ fn parse_ty_data(data: @[u8], crate_num: int, pos: uint, len: uint,
5555
fn parse_ret_ty(st: @pstate, sd: str_def) -> (ast::ret_style, ty::t) {
5656
alt peek(st) as char {
5757
'!' { next(st); (ast::noreturn, ty::mk_bot(st.tcx)) }
58-
'&' | '^' {
59-
let mut = next(st) == '^' as u8;
60-
let arg = next(st) as uint;
61-
(ast::return_ref(mut, arg), parse_ty(st, sd))
62-
}
6358
_ { (ast::return_val, parse_ty(st, sd)) }
6459
}
6560
}

src/comp/metadata/tyencode.rs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -214,11 +214,6 @@ fn enc_ty_fn(w: io::writer, cx: @ctxt, args: [ty::arg], out: ty::t,
214214
}
215215
alt cf {
216216
noreturn. { w.write_char('!'); }
217-
return_ref(mut, arg) {
218-
w.write_char(mut ? '^' : '&');
219-
w.write_bytes([arg as u8]);
220-
enc_ty(w, cx, out);
221-
}
222217
_ { enc_ty(w, cx, out); }
223218
}
224219
}

src/comp/middle/alias.rs

Lines changed: 3 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,8 @@ type binding = @{node_id: node_id,
2828
unsafe_tys: [unsafe_ty],
2929
mutable copied: copied};
3030

31-
tag ret_info { by_ref(bool, node_id); other; }
3231
// FIXME it may be worthwhile to use a linked list of bindings instead
3332
type scope = {bs: [binding],
34-
ret_info: ret_info,
3533
invalid: @mutable list<@invalid>};
3634

3735
fn mk_binding(cx: ctx, id: node_id, span: span, root_var: option::t<node_id>,
@@ -67,7 +65,7 @@ fn check_crate(tcx: ty::ctxt, crate: @ast::crate) -> (copy_map, ref_map) {
6765
visit_expr: bind visit_expr(cx, _, _, _),
6866
visit_block: bind visit_block(cx, _, _, _)
6967
with *visit::default_visitor::<scope>()};
70-
let sc = {bs: [], ret_info: other, invalid: @mutable list::nil};
68+
let sc = {bs: [], invalid: @mutable list::nil};
7169
visit::visit_crate(*crate, sc, visit::mk_vt(v));
7270
tcx.sess.abort_if_errors();
7371
ret (cx.copy_map, cx.ref_map);
@@ -84,24 +82,12 @@ fn visit_fn(cx: @ctx, f: ast::_fn, _tp: [ast::ty_param], sp: span,
8482
}
8583
}
8684

87-
if ast_util::ret_by_ref(f.decl.cf) && !is_none(f.body.node.expr) {
88-
// FIXME this will be easier to lift once have DPS
89-
err(*cx, option::get(f.body.node.expr).span,
90-
"reference-returning functions may not return implicitly");
91-
}
92-
let ret_info = alt f.decl.cf {
93-
ast::return_ref(mut, n_arg) {
94-
by_ref(mut, f.decl.inputs[n_arg - 1u].id)
95-
}
96-
_ { other }
97-
};
9885
// Blocks need to obey any restrictions from the enclosing scope, and may
9986
// be called multiple times.
10087
if f.proto == ast::proto_block {
101-
let sc = {ret_info: ret_info with sc};
10288
check_loop(*cx, sc) {|| v.visit_block(f.body, sc, v);}
10389
} else {
104-
let sc = {bs: [], ret_info: ret_info, invalid: @mutable list::nil};
90+
let sc = {bs: [], invalid: @mutable list::nil};
10591
v.visit_block(f.body, sc, v);
10692
}
10793
}
@@ -134,17 +120,6 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
134120
ast::expr_assign(dest, src) | ast::expr_assign_op(_, dest, src) {
135121
check_assign(cx, dest, src, sc, v);
136122
}
137-
ast::expr_ret(oexpr) {
138-
if !is_none(oexpr) {
139-
alt sc.ret_info {
140-
by_ref(mut, arg_node_id) {
141-
check_ret_ref(*cx, sc, mut, arg_node_id, option::get(oexpr));
142-
}
143-
_ {}
144-
}
145-
}
146-
handled = false;
147-
}
148123
ast::expr_if(c, then, els) { check_if(c, then, els, sc, v); }
149124
ast::expr_while(_, _) | ast::expr_do_while(_, _) {
150125
check_loop(*cx, sc) {|| visit::visit_expr(ex, sc, v); }
@@ -237,9 +212,6 @@ fn cant_copy(cx: ctx, b: binding) -> bool {
237212
fn check_call(cx: ctx, sc: scope, f: @ast::expr, args: [@ast::expr])
238213
-> [binding] {
239214
let fty = ty::expr_ty(cx.tcx, f);
240-
let by_ref = alt ty::ty_fn_ret_style(cx.tcx, fty) {
241-
ast::return_ref(_, arg_n) { arg_n } _ { 0u }
242-
};
243215
let arg_ts = ty::ty_fn_args(cx.tcx, fty);
244216
let mut_roots: [{arg: uint, node: node_id}] = [];
245217
let bindings = [];
@@ -265,7 +237,7 @@ fn check_call(cx: ctx, sc: scope, f: @ast::expr, args: [@ast::expr])
265237
mutable copied: alt arg_t.mode {
266238
ast::by_move. | ast::by_copy. { copied }
267239
ast::by_mut_ref. { not_allowed }
268-
_ { i + 1u == by_ref ? not_allowed : not_copied }
240+
_ { not_copied }
269241
}}];
270242
i += 1u;
271243
}
@@ -338,69 +310,6 @@ fn check_call(cx: ctx, sc: scope, f: @ast::expr, args: [@ast::expr])
338310
ret bindings;
339311
}
340312

341-
fn check_ret_ref(cx: ctx, sc: scope, mut: bool, arg_node_id: node_id,
342-
expr: @ast::expr) {
343-
let root = expr_root(cx, expr, false);
344-
let bad = none;
345-
let mut_field = !is_none(root.mut);
346-
alt path_def(cx, root.ex) {
347-
none. {
348-
bad = some("a temporary");
349-
}
350-
some(ast::def_local(did, _)) | some(ast::def_binding(did)) |
351-
some(ast::def_arg(did, _)) {
352-
let cur_node = did.node;
353-
while true {
354-
alt cx.tcx.items.find(cur_node) {
355-
some(ast_map::node_arg(arg, _)) {
356-
if arg.mode == ast::by_move {
357-
bad = some("a move-mode parameter");
358-
}
359-
if arg.mode == ast::by_copy {
360-
bad = some("a copy-mode parameter");
361-
}
362-
if cur_node != arg_node_id {
363-
bad = some("the wrong parameter");
364-
}
365-
break;
366-
}
367-
_ {}
368-
}
369-
alt vec::find({|b| b.node_id == cur_node}, sc.bs) {
370-
some(b) {
371-
if vec::len(b.unsafe_tys) > 0u {
372-
mut_field = true;
373-
break;
374-
}
375-
if is_none(b.root_var) {
376-
bad = some("a function-local value");
377-
break;
378-
}
379-
if b.copied == copied {
380-
bad = some("an implicitly copied reference");
381-
break;
382-
}
383-
b.copied = not_allowed;
384-
cur_node = option::get(b.root_var);
385-
}
386-
none. {
387-
bad = some("a function-local value");
388-
break;
389-
}
390-
}
391-
}
392-
}
393-
_ { bad = some("a non-local value"); }
394-
}
395-
if mut_field && !mut { bad = some("a mutable field"); }
396-
alt bad {
397-
some(name) {
398-
err(cx, expr.span, "can not return a reference to " + name);
399-
}
400-
_ {}
401-
}
402-
}
403-
404313
fn check_alt(cx: ctx, input: @ast::expr, arms: [ast::arm], sc: scope,
405314
v: vt<scope>) {
406315
v.visit_expr(input, sc, v);
@@ -733,22 +642,6 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool)
733642
_ {}
734643
}
735644
}
736-
ast::expr_call(f, args, _) {
737-
let fty = ty::expr_ty(cx.tcx, f);
738-
alt ty::ty_fn_ret_style(cx.tcx, fty) {
739-
ast::return_ref(mut, arg_n) {
740-
let arg = args[arg_n - 1u];
741-
let arg_root = expr_root(cx, arg, false);
742-
if mut {
743-
let ret_ty = ty::expr_ty(cx.tcx, base_root.ex);
744-
unsafe_ty = some(mut_contains(ret_ty));
745-
}
746-
if !is_none(arg_root.mut) { unsafe_ty = arg_root.mut; }
747-
ret {ex: arg_root.ex, mut: unsafe_ty};
748-
}
749-
_ {}
750-
}
751-
}
752645
_ {}
753646
}
754647
ret {ex: base_root.ex, mut: unsafe_ty};

src/comp/middle/kind.rs

Lines changed: 4 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -30,19 +30,16 @@ type rval_map = std::map::hashmap<node_id, ()>;
3030

3131
type ctx = {tcx: ty::ctxt,
3232
rval_map: rval_map,
33-
last_uses: last_use::last_uses,
34-
mutable ret_by_ref: bool};
33+
last_uses: last_use::last_uses};
3534

3635
fn check_crate(tcx: ty::ctxt, last_uses: last_use::last_uses,
3736
crate: @crate) -> rval_map {
3837
let ctx = {tcx: tcx,
3938
rval_map: std::map::new_int_hash(),
40-
last_uses: last_uses,
41-
mutable ret_by_ref: false};
39+
last_uses: last_uses};
4240
let visit = visit::mk_vt(@{
4341
visit_expr: check_expr,
44-
visit_stmt: check_stmt,
45-
visit_fn: visit_fn
42+
visit_stmt: check_stmt
4643
with *visit::default_visitor()
4744
});
4845
visit::visit_crate(*crate, ctx, visit);
@@ -55,7 +52,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt<ctx>) {
5552
expr_assign(_, ex) | expr_assign_op(_, _, ex) |
5653
expr_block({node: {expr: some(ex), _}, _}) |
5754
expr_unary(box(_), ex) | expr_unary(uniq(_), ex) { maybe_copy(cx, ex); }
58-
expr_ret(some(ex)) { if !cx.ret_by_ref { maybe_copy(cx, ex); } }
55+
expr_ret(some(ex)) { maybe_copy(cx, ex); }
5956
expr_copy(expr) { check_copy_ex(cx, expr, false); }
6057
// Vector add copies.
6158
expr_binary(add., ls, rs) { maybe_copy(cx, ls); maybe_copy(cx, rs); }
@@ -138,14 +135,6 @@ fn check_stmt(stmt: @stmt, cx: ctx, v: visit::vt<ctx>) {
138135
visit::visit_stmt(stmt, cx, v);
139136
}
140137

141-
fn visit_fn(f: _fn, tps: [ty_param], sp: span, ident: fn_ident,
142-
id: node_id, cx: ctx, v: visit::vt<ctx>) {
143-
let old_ret = cx.ret_by_ref;
144-
cx.ret_by_ref = ast_util::ret_by_ref(f.decl.cf);
145-
visit::visit_fn(f, tps, sp, ident, id, cx, v);
146-
cx.ret_by_ref = old_ret;
147-
}
148-
149138
fn maybe_copy(cx: ctx, ex: @expr) {
150139
check_copy_ex(cx, ex, true);
151140
}

0 commit comments

Comments
 (0)