diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index 3a09f6db883f..70e87824ad0d 100644 --- a/src/comp/metadata/tydecode.rs +++ b/src/comp/metadata/tydecode.rs @@ -55,11 +55,6 @@ fn parse_ty_data(data: @[u8], crate_num: int, pos: uint, len: uint, fn parse_ret_ty(st: @pstate, sd: str_def) -> (ast::ret_style, ty::t) { alt peek(st) as char { '!' { next(st); (ast::noreturn, ty::mk_bot(st.tcx)) } - '&' | '^' { - let mut = next(st) == '^' as u8; - let arg = next(st) as uint; - (ast::return_ref(mut, arg), parse_ty(st, sd)) - } _ { (ast::return_val, parse_ty(st, sd)) } } } diff --git a/src/comp/metadata/tyencode.rs b/src/comp/metadata/tyencode.rs index 029127445d0f..4f3d51e0714e 100644 --- a/src/comp/metadata/tyencode.rs +++ b/src/comp/metadata/tyencode.rs @@ -214,11 +214,6 @@ fn enc_ty_fn(w: io::writer, cx: @ctxt, args: [ty::arg], out: ty::t, } alt cf { noreturn. { w.write_char('!'); } - return_ref(mut, arg) { - w.write_char(mut ? '^' : '&'); - w.write_bytes([arg as u8]); - enc_ty(w, cx, out); - } _ { enc_ty(w, cx, out); } } } diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index 7e05e9186c3e..e3353e3d4830 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -28,10 +28,8 @@ type binding = @{node_id: node_id, unsafe_tys: [unsafe_ty], mutable copied: copied}; -tag ret_info { by_ref(bool, node_id); other; } // FIXME it may be worthwhile to use a linked list of bindings instead type scope = {bs: [binding], - ret_info: ret_info, invalid: @mutable list<@invalid>}; fn mk_binding(cx: ctx, id: node_id, span: span, root_var: option::t, @@ -67,7 +65,7 @@ fn check_crate(tcx: ty::ctxt, crate: @ast::crate) -> (copy_map, ref_map) { visit_expr: bind visit_expr(cx, _, _, _), visit_block: bind visit_block(cx, _, _, _) with *visit::default_visitor::()}; - let sc = {bs: [], ret_info: other, invalid: @mutable list::nil}; + let sc = {bs: [], invalid: @mutable list::nil}; visit::visit_crate(*crate, sc, visit::mk_vt(v)); tcx.sess.abort_if_errors(); 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, } } - if ast_util::ret_by_ref(f.decl.cf) && !is_none(f.body.node.expr) { - // FIXME this will be easier to lift once have DPS - err(*cx, option::get(f.body.node.expr).span, - "reference-returning functions may not return implicitly"); - } - let ret_info = alt f.decl.cf { - ast::return_ref(mut, n_arg) { - by_ref(mut, f.decl.inputs[n_arg - 1u].id) - } - _ { other } - }; // Blocks need to obey any restrictions from the enclosing scope, and may // be called multiple times. if f.proto == ast::proto_block { - let sc = {ret_info: ret_info with sc}; check_loop(*cx, sc) {|| v.visit_block(f.body, sc, v);} } else { - let sc = {bs: [], ret_info: ret_info, invalid: @mutable list::nil}; + let sc = {bs: [], invalid: @mutable list::nil}; v.visit_block(f.body, sc, v); } } @@ -134,17 +120,6 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt) { ast::expr_assign(dest, src) | ast::expr_assign_op(_, dest, src) { check_assign(cx, dest, src, sc, v); } - ast::expr_ret(oexpr) { - if !is_none(oexpr) { - alt sc.ret_info { - by_ref(mut, arg_node_id) { - check_ret_ref(*cx, sc, mut, arg_node_id, option::get(oexpr)); - } - _ {} - } - } - handled = false; - } ast::expr_if(c, then, els) { check_if(c, then, els, sc, v); } ast::expr_while(_, _) | ast::expr_do_while(_, _) { check_loop(*cx, sc) {|| visit::visit_expr(ex, sc, v); } @@ -237,9 +212,6 @@ fn cant_copy(cx: ctx, b: binding) -> bool { fn check_call(cx: ctx, sc: scope, f: @ast::expr, args: [@ast::expr]) -> [binding] { let fty = ty::expr_ty(cx.tcx, f); - let by_ref = alt ty::ty_fn_ret_style(cx.tcx, fty) { - ast::return_ref(_, arg_n) { arg_n } _ { 0u } - }; let arg_ts = ty::ty_fn_args(cx.tcx, fty); let mut_roots: [{arg: uint, node: node_id}] = []; let bindings = []; @@ -265,7 +237,7 @@ fn check_call(cx: ctx, sc: scope, f: @ast::expr, args: [@ast::expr]) mutable copied: alt arg_t.mode { ast::by_move. | ast::by_copy. { copied } ast::by_mut_ref. { not_allowed } - _ { i + 1u == by_ref ? not_allowed : not_copied } + _ { not_copied } }}]; i += 1u; } @@ -338,69 +310,6 @@ fn check_call(cx: ctx, sc: scope, f: @ast::expr, args: [@ast::expr]) ret bindings; } -fn check_ret_ref(cx: ctx, sc: scope, mut: bool, arg_node_id: node_id, - expr: @ast::expr) { - let root = expr_root(cx, expr, false); - let bad = none; - let mut_field = !is_none(root.mut); - alt path_def(cx, root.ex) { - none. { - bad = some("a temporary"); - } - some(ast::def_local(did, _)) | some(ast::def_binding(did)) | - some(ast::def_arg(did, _)) { - let cur_node = did.node; - while true { - alt cx.tcx.items.find(cur_node) { - some(ast_map::node_arg(arg, _)) { - if arg.mode == ast::by_move { - bad = some("a move-mode parameter"); - } - if arg.mode == ast::by_copy { - bad = some("a copy-mode parameter"); - } - if cur_node != arg_node_id { - bad = some("the wrong parameter"); - } - break; - } - _ {} - } - alt vec::find({|b| b.node_id == cur_node}, sc.bs) { - some(b) { - if vec::len(b.unsafe_tys) > 0u { - mut_field = true; - break; - } - if is_none(b.root_var) { - bad = some("a function-local value"); - break; - } - if b.copied == copied { - bad = some("an implicitly copied reference"); - break; - } - b.copied = not_allowed; - cur_node = option::get(b.root_var); - } - none. { - bad = some("a function-local value"); - break; - } - } - } - } - _ { bad = some("a non-local value"); } - } - if mut_field && !mut { bad = some("a mutable field"); } - alt bad { - some(name) { - err(cx, expr.span, "can not return a reference to " + name); - } - _ {} - } -} - fn check_alt(cx: ctx, input: @ast::expr, arms: [ast::arm], sc: scope, v: vt) { v.visit_expr(input, sc, v); @@ -733,22 +642,6 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool) _ {} } } - ast::expr_call(f, args, _) { - let fty = ty::expr_ty(cx.tcx, f); - alt ty::ty_fn_ret_style(cx.tcx, fty) { - ast::return_ref(mut, arg_n) { - let arg = args[arg_n - 1u]; - let arg_root = expr_root(cx, arg, false); - if mut { - let ret_ty = ty::expr_ty(cx.tcx, base_root.ex); - unsafe_ty = some(mut_contains(ret_ty)); - } - if !is_none(arg_root.mut) { unsafe_ty = arg_root.mut; } - ret {ex: arg_root.ex, mut: unsafe_ty}; - } - _ {} - } - } _ {} } ret {ex: base_root.ex, mut: unsafe_ty}; diff --git a/src/comp/middle/kind.rs b/src/comp/middle/kind.rs index 42dfbd1cb6fc..32f249132863 100644 --- a/src/comp/middle/kind.rs +++ b/src/comp/middle/kind.rs @@ -30,19 +30,16 @@ type rval_map = std::map::hashmap; type ctx = {tcx: ty::ctxt, rval_map: rval_map, - last_uses: last_use::last_uses, - mutable ret_by_ref: bool}; + last_uses: last_use::last_uses}; fn check_crate(tcx: ty::ctxt, last_uses: last_use::last_uses, crate: @crate) -> rval_map { let ctx = {tcx: tcx, rval_map: std::map::new_int_hash(), - last_uses: last_uses, - mutable ret_by_ref: false}; + last_uses: last_uses}; let visit = visit::mk_vt(@{ visit_expr: check_expr, - visit_stmt: check_stmt, - visit_fn: visit_fn + visit_stmt: check_stmt with *visit::default_visitor() }); visit::visit_crate(*crate, ctx, visit); @@ -55,7 +52,7 @@ fn check_expr(e: @expr, cx: ctx, v: visit::vt) { expr_assign(_, ex) | expr_assign_op(_, _, ex) | expr_block({node: {expr: some(ex), _}, _}) | expr_unary(box(_), ex) | expr_unary(uniq(_), ex) { maybe_copy(cx, ex); } - expr_ret(some(ex)) { if !cx.ret_by_ref { maybe_copy(cx, ex); } } + expr_ret(some(ex)) { maybe_copy(cx, ex); } expr_copy(expr) { check_copy_ex(cx, expr, false); } // Vector add copies. 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) { visit::visit_stmt(stmt, cx, v); } -fn visit_fn(f: _fn, tps: [ty_param], sp: span, ident: fn_ident, - id: node_id, cx: ctx, v: visit::vt) { - let old_ret = cx.ret_by_ref; - cx.ret_by_ref = ast_util::ret_by_ref(f.decl.cf); - visit::visit_fn(f, tps, sp, ident, id, cx, v); - cx.ret_by_ref = old_ret; -} - fn maybe_copy(cx: ctx, ex: @expr) { check_copy_ex(cx, ex, true); } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 1a867f28b7b1..624a168ef634 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -80,14 +80,14 @@ fn type_of_explicit_args(cx: @crate_ctxt, sp: span, inputs: [ty::arg]) -> // - new_fn_ctxt // - trans_args fn type_of_fn(cx: @crate_ctxt, sp: span, - is_method: bool, ret_ref: bool, inputs: [ty::arg], + is_method: bool, inputs: [ty::arg], output: ty::t, ty_param_count: uint) : non_ty_var(cx, output) -> TypeRef { let atys: [TypeRef] = []; // Arg 0: Output pointer. let out_ty = T_ptr(type_of_inner(cx, sp, output)); - atys += [ret_ref ? T_ptr(out_ty) : out_ty]; + atys += [out_ty]; // Arg 1: Env (closure-bindings / self-obj) if is_method { @@ -108,13 +108,12 @@ fn type_of_fn(cx: @crate_ctxt, sp: span, fn type_of_fn_from_ty(cx: @crate_ctxt, sp: span, fty: ty::t, ty_param_count: uint) : returns_non_ty_var(cx, fty) -> TypeRef { - let by_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(cx.tcx, fty)); // FIXME: Check should be unnecessary, b/c it's implied // by returns_non_ty_var(t). Make that a postcondition // (see Issue #586) let ret_ty = ty::ty_fn_ret(cx.tcx, fty); check non_ty_var(cx, ret_ty); - ret type_of_fn(cx, sp, false, by_ref, ty::ty_fn_args(cx.tcx, fty), + ret type_of_fn(cx, sp, false, ty::ty_fn_args(cx.tcx, fty), ret_ty, ty_param_count); } @@ -3046,11 +3045,10 @@ fn trans_object_field_inner(bcx: @block_ctxt, o: ValueRef, let v = GEPi(bcx, vtbl, [0, ix as int]); let fn_ty: ty::t = ty::method_ty_to_fn_ty(tcx, mths[ix]); let ret_ty = ty::ty_fn_ret(tcx, fn_ty); - let ret_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(tcx, fn_ty)); // FIXME: constrain ty_obj? check non_ty_var(ccx, ret_ty); - let ll_fn_ty = type_of_fn(ccx, bcx.sp, true, ret_ref, + let ll_fn_ty = type_of_fn(ccx, bcx.sp, true, ty::ty_fn_args(tcx, fn_ty), ret_ty, 0u); v = Load(bcx, PointerCast(bcx, v, T_ptr(T_ptr(ll_fn_ty)))); ret {bcx: bcx, mthptr: v, objptr: o}; @@ -3656,16 +3654,14 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty0: TypeRef, // - create_llargs_for_fn_args. // - new_fn_ctxt // - trans_args -fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef, +fn trans_args(cx: @block_ctxt, llenv: ValueRef, gen: option::t, es: [@ast::expr], fn_ty: ty::t, dest: dest) -> {bcx: @block_ctxt, - outer_cx: @block_ctxt, args: [ValueRef], retslot: ValueRef, to_zero: [{v: ValueRef, t: ty::t}], - to_revoke: [{v: ValueRef, t: ty::t}], - ret_ref: bool} { + to_revoke: [{v: ValueRef, t: ty::t}]} { let args: [ty::arg] = ty::ty_fn_args(bcx_tcx(cx), fn_ty); let llargs: [ValueRef] = []; @@ -3676,8 +3672,6 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef, let ccx = bcx_ccx(cx); let tcx = ccx.tcx; let bcx = cx; - let ret_style = ty::ty_fn_ret_style(tcx, fn_ty); - let ret_ref = ast_util::ret_by_ref(ret_style); let retty = ty::ty_fn_ret(tcx, fn_ty), full_retty = retty; alt gen { @@ -3691,18 +3685,14 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef, } // Arg 0: Output pointer. let llretty = type_of_or_i8(bcx, full_retty); - let llretslot = if ret_ref { - alloca(cx, T_ptr(llretty)) - } else { - alt dest { - ignore. { - if ty::type_is_nil(tcx, retty) { - llvm::LLVMGetUndef(T_ptr(llretty)) - } else { alloca(cx, llretty) } - } - save_in(dst) { dst } - by_val(_) { alloca(cx, llretty) } - } + let llretslot = alt dest { + ignore. { + if ty::type_is_nil(tcx, retty) { + llvm::LLVMGetUndef(T_ptr(llretty)) + } else { alloca(cx, llretty) } + } + save_in(dst) { dst } + by_val(_) { alloca(cx, llretty) } }; if ty::type_contains_params(tcx, retty) { @@ -3713,7 +3703,6 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef, // view, for the sake of making a type-compatible call. check non_ty_var(ccx, retty); let llretty = T_ptr(type_of_inner(ccx, bcx.sp, retty)); - if ret_ref { llretty = T_ptr(llretty); } llargs += [PointerCast(cx, llretslot, llretty)]; } else { llargs += [llretslot]; } @@ -3729,25 +3718,19 @@ fn trans_args(cx: @block_ctxt, outer_cx: @block_ctxt, llenv: ValueRef, // This will be needed if this is a generic call, because the callee has // to cast her view of the arguments to the caller's view. let arg_tys = type_of_explicit_args(ccx, cx.sp, args); - let i = 0u, outer_cx = outer_cx; + let i = 0u; for e: @ast::expr in es { - let is_referenced = alt ret_style { - ast::return_ref(_, arg_n) { i + 1u == arg_n } - _ { false } - }; - let r = trans_arg_expr(is_referenced ? outer_cx : bcx, - args[i], arg_tys[i], to_zero, to_revoke, e); - if is_referenced { outer_cx = r.bcx; } else { bcx = r.bcx; } + let r = trans_arg_expr(bcx, args[i], arg_tys[i], to_zero, to_revoke, + e); + bcx = r.bcx; llargs += [r.val]; i += 1u; } ret {bcx: bcx, - outer_cx: outer_cx, args: llargs, retslot: llretslot, to_zero: to_zero, - to_revoke: to_revoke, - ret_ref: ret_ref}; + to_revoke: to_revoke}; } fn trans_call(in_cx: @block_ctxt, f: @ast::expr, @@ -3764,6 +3747,7 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr, //NDM } let cx = new_scope_block_ctxt(in_cx, "call"); + Br(in_cx, cx.llbb); let f_res = trans_callee(cx, f); let bcx = f_res.bcx; @@ -3789,8 +3773,7 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr, let ret_ty = ty::node_id_to_type(tcx, id); let args_res = - trans_args(bcx, in_cx, llenv, f_res.generic, args, fn_expr_ty, dest); - Br(args_res.outer_cx, cx.llbb); + trans_args(bcx, llenv, f_res.generic, args, fn_expr_ty, dest); bcx = args_res.bcx; let llargs = args_res.args; let llretslot = args_res.retslot; @@ -3803,8 +3786,7 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr, args_res.to_revoke); alt dest { ignore. { - if llvm::LLVMIsUndef(llretslot) != lib::llvm::True && - !args_res.ret_ref { + if llvm::LLVMIsUndef(llretslot) != lib::llvm::True { bcx = drop_ty(bcx, llretslot, ret_ty); } } @@ -4445,16 +4427,7 @@ fn trans_cont(sp: span, cx: @block_ctxt) -> @block_ctxt { fn trans_ret(bcx: @block_ctxt, e: option::t<@ast::expr>) -> @block_ctxt { let cleanup_cx = bcx, bcx = bcx; alt e { - some(x) { - if ast_util::ret_by_ref(bcx.fcx.ret_style) { - let {bcx: cx, val, kind} = trans_lval(bcx, x); - assert kind == owned; - Store(cx, val, bcx.fcx.llretptr); - bcx = cx; - } else { - bcx = trans_expr_save_in(bcx, x, bcx.fcx.llretptr); - } - } + some(x) { bcx = trans_expr_save_in(bcx, x, bcx.fcx.llretptr); } _ {} } // run all cleanups and back out. @@ -5604,7 +5577,7 @@ fn create_main_wrapper(ccx: @crate_ctxt, sp: span, main_llfn: ValueRef, let nt = ty::mk_nil(ccx.tcx); check non_ty_var(ccx, nt); - let llfty = type_of_fn(ccx, sp, false, false, [vecarg_ty], nt, 0u); + let llfty = type_of_fn(ccx, sp, false, [vecarg_ty], nt, 0u); let llfdecl = decl_fn(ccx.llmod, "_rust_main", lib::llvm::LLVMCCallConv, llfty); @@ -5700,7 +5673,7 @@ fn native_fn_wrapper_type(cx: @crate_ctxt, sp: span, ty_param_count: uint, alt ty::struct(cx.tcx, x) { ty::ty_native_fn(args, out) { check non_ty_var(cx, out); - ret type_of_fn(cx, sp, false, false, args, out, ty_param_count); + ret type_of_fn(cx, sp, false, args, out, ty_param_count); } } } diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index c99b6197c83f..e77ce6c8d5fb 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -321,7 +321,7 @@ fn get_res_dtor(ccx: @crate_ctxt, sp: span, did: ast::def_id, inner_t: ty::t) let nil_res = ty::mk_nil(ccx.tcx); // FIXME: Silly check -- mk_nil should have a postcondition check non_ty_var(ccx, nil_res); - let f_t = type_of_fn(ccx, sp, false, false, + let f_t = type_of_fn(ccx, sp, false, [{mode: ast::by_ref, ty: inner_t}], nil_res, params); ret trans::get_extern_const(ccx.externs, ccx.llmod, @@ -430,14 +430,14 @@ fn find_scope_cx(cx: @block_ctxt) -> @block_ctxt { // Accessors // TODO: When we have overloading, simplify these names! -pure fn bcx_tcx(bcx: @block_ctxt) -> &ty::ctxt { ret bcx.fcx.lcx.ccx.tcx; } -pure fn bcx_ccx(bcx: @block_ctxt) -> &@crate_ctxt { ret bcx.fcx.lcx.ccx; } -pure fn bcx_lcx(bcx: @block_ctxt) -> &@local_ctxt { ret bcx.fcx.lcx; } -pure fn bcx_fcx(bcx: @block_ctxt) -> &@fn_ctxt { ret bcx.fcx; } -pure fn fcx_ccx(fcx: @fn_ctxt) -> &@crate_ctxt { ret fcx.lcx.ccx; } -pure fn fcx_tcx(fcx: @fn_ctxt) -> &ty::ctxt { ret fcx.lcx.ccx.tcx; } -pure fn lcx_ccx(lcx: @local_ctxt) -> &@crate_ctxt { ret lcx.ccx; } -pure fn ccx_tcx(ccx: @crate_ctxt) -> &ty::ctxt { ret ccx.tcx; } +pure fn bcx_tcx(bcx: @block_ctxt) -> ty::ctxt { ret bcx.fcx.lcx.ccx.tcx; } +pure fn bcx_ccx(bcx: @block_ctxt) -> @crate_ctxt { ret bcx.fcx.lcx.ccx; } +pure fn bcx_lcx(bcx: @block_ctxt) -> @local_ctxt { ret bcx.fcx.lcx; } +pure fn bcx_fcx(bcx: @block_ctxt) -> @fn_ctxt { ret bcx.fcx; } +pure fn fcx_ccx(fcx: @fn_ctxt) -> @crate_ctxt { ret fcx.lcx.ccx; } +pure fn fcx_tcx(fcx: @fn_ctxt) -> ty::ctxt { ret fcx.lcx.ccx.tcx; } +pure fn lcx_ccx(lcx: @local_ctxt) -> @crate_ctxt { ret lcx.ccx; } +pure fn ccx_tcx(ccx: @crate_ctxt) -> ty::ctxt { ret ccx.tcx; } // LLVM type constructors. fn T_void() -> TypeRef { diff --git a/src/comp/middle/trans_objects.rs b/src/comp/middle/trans_objects.rs index d9f25b801a0a..ba3e32c411a7 100644 --- a/src/comp/middle/trans_objects.rs +++ b/src/comp/middle/trans_objects.rs @@ -879,8 +879,7 @@ fn process_normal_mthd(cx: @local_ctxt, m: @ast::method, self_ty: ty::t, alt ty::struct(cx.ccx.tcx, node_id_type(cx.ccx, m.node.id)) { ty::ty_fn(_, inputs, output, rs, _) { check non_ty_var(ccx, output); - llfnty = type_of_fn(ccx, m.span, true, - ast_util::ret_by_ref(rs), inputs, output, + llfnty = type_of_fn(ccx, m.span, true, inputs, output, vec::len(ty_params)); } } @@ -933,8 +932,7 @@ fn type_of_meth(ccx: @crate_ctxt, sp: span, m: @ty::method, tps: [ast::ty_param]) -> TypeRef { let out_ty = m.output; check non_ty_var(ccx, out_ty); - type_of_fn(ccx, sp, true, ast_util::ret_by_ref(m.cf), - m.inputs, out_ty, vec::len(tps)) + type_of_fn(ccx, sp, true, m.inputs, out_ty, vec::len(tps)) } // diff --git a/src/comp/middle/ty.rs b/src/comp/middle/ty.rs index be472ff54ebd..e3615d697ba7 100644 --- a/src/comp/middle/ty.rs +++ b/src/comp/middle/ty.rs @@ -1670,10 +1670,6 @@ fn expr_is_lval(tcx: ty::ctxt, e: @ast::expr) -> bool { ty_rec(_) { true } } } - ast::expr_call(f, _, _) { - let fty = expr_ty(tcx, f); - ast_util::ret_by_ref(ty_fn_ret_style(tcx, fty)) - } _ { false } } } @@ -2623,10 +2619,6 @@ fn type_err_to_str(err: ty::type_err) -> str { alt s { ast::noreturn. { "non-returning" } ast::return_val. { "return-by-value" } - ast::return_ref(mut, arg) { - #fmt("return-by-%sreference on arg %u", - mut ? "mutable-" : "", arg) - } } } ret to_str(actual) + " function found where " + to_str(expect) + diff --git a/src/comp/syntax/ast.rs b/src/comp/syntax/ast.rs index dfebf9135fdf..b1e1a16c6af4 100644 --- a/src/comp/syntax/ast.rs +++ b/src/comp/syntax/ast.rs @@ -397,7 +397,6 @@ tag ret_style { noreturn; // functions with return type _|_ that always // raise an error or exit (i.e. never return to the caller) return_val; // everything else - return_ref(bool, uint); } type _fn = {decl: fn_decl, proto: proto, body: blk}; diff --git a/src/comp/syntax/ast_util.rs b/src/comp/syntax/ast_util.rs index c68092da90d5..862d182b9fd3 100644 --- a/src/comp/syntax/ast_util.rs +++ b/src/comp/syntax/ast_util.rs @@ -223,13 +223,6 @@ fn ternary_to_if(e: @expr) -> @expr { } } -fn ret_by_ref(style: ret_style) -> bool { - alt style { - return_ref(_, _) { true } - _ { false } - } -} - fn ty_param_kind(tp: ty_param) -> kind { tp.kind } fn compare_lit(a: @lit, b: @lit) -> int { diff --git a/src/comp/syntax/parse/parser.rs b/src/comp/syntax/parse/parser.rs index 35c1e1190d3e..391d5eb88195 100644 --- a/src/comp/syntax/parse/parser.rs +++ b/src/comp/syntax/parse/parser.rs @@ -295,7 +295,7 @@ fn parse_ty_fn(proto: ast::proto, p: parser) -> ast::ty_ { // FIXME: there's no syntax for this right now anyway // auto constrs = parse_constrs(~[], p); let constrs: [@ast::constr] = []; - let (ret_style, ret_ty) = parse_ret_ty(p, vec::len(inputs.node)); + let (ret_style, ret_ty) = parse_ret_ty(p); ret ast::ty_fn(proto, inputs.node, ret_ty, ret_style, constrs); } @@ -439,34 +439,12 @@ fn parse_ty_postfix(orig_t: ast::ty_, p: parser, colons_before_params: bool) } } -fn parse_ret_ty(p: parser, n_args: uint) -> (ast::ret_style, @ast::ty) { +fn parse_ret_ty(p: parser) -> (ast::ret_style, @ast::ty) { ret if eat(p, token::RARROW) { let lo = p.get_lo_pos(); if eat(p, token::NOT) { (ast::noreturn, @spanned(lo, p.get_last_hi_pos(), ast::ty_bot)) - } else { - let style = ast::return_val; - if eat(p, token::BINOP(token::AND)) { - if n_args == 0u { - p.fatal("can not return reference from argument-less fn"); - } - let mut_root = eat(p, token::NOT), arg = 1u; - alt p.peek() { - token::LIT_INT(val) { p.bump(); arg = val as uint; } - _ { if n_args > 1u { - p.fatal("must specify referenced parameter"); - } } - } - if arg > n_args { - p.fatal("referenced argument does not exist"); - } - if arg == 0u { - p.fatal("referenced argument can't be 0"); - } - style = ast::return_ref(mut_root, arg); - }; - (style, parse_ty(p, false)) - } + } else { (ast::return_val, parse_ty(p, false)) } } else { let pos = p.get_lo_pos(); (ast::return_val, @spanned(pos, pos, ast::ty_nil)) @@ -1791,7 +1769,7 @@ fn parse_fn_decl(p: parser, purity: ast::purity, il: ast::inlineness) -> p.bump(); constrs = parse_constrs({|x| parse_ty_constr(inputs.node, x) }, p); } - let (ret_style, ret_ty) = parse_ret_ty(p, vec::len(inputs.node)); + let (ret_style, ret_ty) = parse_ret_ty(p); ret {inputs: inputs.node, output: ret_ty, purity: purity, diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index 7da57be49103..0fb5df69edbe 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -1130,15 +1130,6 @@ fn print_fn_args_and_ret(s: ps, decl: ast::fn_decl, constrs: [@ast::constr]) { if decl.output.node != ast::ty_nil { space_if_not_bol(s); word_space(s, "->"); - alt decl.cf { - ast::return_ref(mut, arg) { - word(s.s, mut ? "&!" : "&"); - if vec::len(decl.inputs) > 1u { - word_space(s, std::uint::str(arg)); - } - } - _ {} - } print_type(s, decl.output); } } @@ -1336,18 +1327,8 @@ fn print_ty_fn(s: ps, proto: ast::proto, id: option::t, space_if_not_bol(s); ibox(s, indent_unit); word_space(s, "->"); - if cf == ast::noreturn { - word_nbsp(s, "!"); - } else { - alt cf { - ast::return_ref(mut, arg) { - word(s.s, mut ? "&!" : "&"); - if vec::len(inputs) > 1u { word(s.s, std::uint::str(arg)); } - } - _ {} - } - print_type(s, output); - } + if cf == ast::noreturn { word_nbsp(s, "!"); } + else { print_type(s, output); } end(s); } word(s.s, ast_ty_fn_constrs_str(constrs)); diff --git a/src/comp/util/ppaux.rs b/src/comp/util/ppaux.rs index 03af32428bb9..d35d871ce656 100644 --- a/src/comp/util/ppaux.rs +++ b/src/comp/util/ppaux.rs @@ -62,11 +62,6 @@ fn ty_to_str(cx: ctxt, typ: t) -> str { s += " -> "; alt cf { ast::noreturn. { s += "!"; } - ast::return_ref(mut, arg) { - s += mut ? "&!" : "&"; - if vec::len(inputs) > 1u { s += std::uint::str(arg); } - s += ty_to_str(cx, output); - } ast::return_val. { s += ty_to_str(cx, output); } } } diff --git a/src/lib/option.rs b/src/lib/option.rs index 2dc25540ca8b..403cb47f47e6 100644 --- a/src/lib/option.rs +++ b/src/lib/option.rs @@ -30,7 +30,7 @@ Failure: Fails if the value equals `none`. */ -fn get(opt: t) -> &T { +fn get(opt: t) -> T { alt opt { some(x) { ret x; } none. { fail "option none"; } } } diff --git a/src/test/compile-fail/ret-by-reference-from-temporary.rs b/src/test/compile-fail/ret-by-reference-from-temporary.rs deleted file mode 100644 index 2a6d05f23d4a..000000000000 --- a/src/test/compile-fail/ret-by-reference-from-temporary.rs +++ /dev/null @@ -1,9 +0,0 @@ -// error-pattern:a reference binding can't be rooted in a temporary - -fn f(a: {x: int}) -> &int { - ret a.x; -} - -fn main() { - let &_a = f({x: 4}); -} diff --git a/src/test/compile-fail/ret-by-reference-local-value.rs b/src/test/compile-fail/ret-by-reference-local-value.rs deleted file mode 100644 index 5e0df4fc3cdf..000000000000 --- a/src/test/compile-fail/ret-by-reference-local-value.rs +++ /dev/null @@ -1,8 +0,0 @@ -// error-pattern:can not return a reference to a function-local value - -fn f(a: {mutable x: int}) -> &int { - let x = {y: 4}; - ret x.y; -} - -fn main() {} diff --git a/src/test/compile-fail/ret-by-reference-mutable-field.rs b/src/test/compile-fail/ret-by-reference-mutable-field.rs deleted file mode 100644 index a40b9aeba2de..000000000000 --- a/src/test/compile-fail/ret-by-reference-mutable-field.rs +++ /dev/null @@ -1,7 +0,0 @@ -// error-pattern:can not return a reference to a mutable field - -fn f(a: {mutable x: int}) -> &int { - ret a.x; -} - -fn main() {} diff --git a/src/test/compile-fail/ret-by-reference-safety-1.rs b/src/test/compile-fail/ret-by-reference-safety-1.rs deleted file mode 100644 index f6cd81308e94..000000000000 --- a/src/test/compile-fail/ret-by-reference-safety-1.rs +++ /dev/null @@ -1,12 +0,0 @@ -// error-pattern:taking the value of x will invalidate reference a - -fn f(a: {mutable x: int}) -> &!int { - ret a.x; -} - -fn main() { - let x = {mutable x: 4}; - let &a = f(x); - x; - a; -} diff --git a/src/test/compile-fail/ret-by-reference-safety-2.rs b/src/test/compile-fail/ret-by-reference-safety-2.rs deleted file mode 100644 index 546511419c13..000000000000 --- a/src/test/compile-fail/ret-by-reference-safety-2.rs +++ /dev/null @@ -1,12 +0,0 @@ -// error-pattern:overwriting x will invalidate reference a - -fn f(a: {x: {mutable x: int}}) -> &{mutable x: int} { - ret a.x; -} - -fn main() { - let x = {x: {mutable x: 4}}; - let &a = f(x); - x = {x: {mutable x: 5}}; - a; -} diff --git a/src/test/compile-fail/ret-by-reference-specify-param.rs b/src/test/compile-fail/ret-by-reference-specify-param.rs deleted file mode 100644 index a99dfc1c8dd9..000000000000 --- a/src/test/compile-fail/ret-by-reference-specify-param.rs +++ /dev/null @@ -1,7 +0,0 @@ -// error-pattern:must specify referenced parameter - -fn f(a: int, b: int) -> &int { - ret a; -} - -fn main() {} diff --git a/src/test/compile-fail/ret-by-reference-temporary.rs b/src/test/compile-fail/ret-by-reference-temporary.rs deleted file mode 100644 index 5a571cf3ecc8..000000000000 --- a/src/test/compile-fail/ret-by-reference-temporary.rs +++ /dev/null @@ -1,7 +0,0 @@ -// error-pattern:can not return a reference to a temporary - -fn f(a: int) -> &int { - ret 10; -} - -fn main() {} diff --git a/src/test/compile-fail/ret-by-reference-wrong-param.rs b/src/test/compile-fail/ret-by-reference-wrong-param.rs deleted file mode 100644 index 7c4791248057..000000000000 --- a/src/test/compile-fail/ret-by-reference-wrong-param.rs +++ /dev/null @@ -1,7 +0,0 @@ -// error-pattern:can not return a reference to the wrong parameter - -fn f(a: int, b: int) -> &2 int { - ret a; -} - -fn main() {} diff --git a/src/test/run-pass/ret-by-reference.rs b/src/test/run-pass/ret-by-reference.rs deleted file mode 100644 index 9c2324a21691..000000000000 --- a/src/test/run-pass/ret-by-reference.rs +++ /dev/null @@ -1,32 +0,0 @@ -tag option { some(T); none; } - -fn get(opt: option) -> &T { - alt opt { - some(x) { ret x; } - } -} - -fn get_mut(a: {mutable x: @int}, _b: int) -> &!1 @int { - ret a.x; -} - -fn get_deep(a: {mutable y: {mutable x: @int}}) -> &!@int { - ret get_mut(a.y, 1); -} - -fn main() { - let x = some(@50); - let &y = get(x); - assert *y == 50; - assert get(some(10)) == 10; - - let y = {mutable x: @50}; - let &box = get_mut(y, 4); - assert *box == 50; - assert *get_mut({mutable x: @70}, 5) == 70; - - let u = {mutable y: {mutable x: @10}}; - let &deep = get_deep(u); - assert *deep == 10; - assert *get_deep({mutable y: {mutable x: @11}}) + 2 == 13; -}