From f8a35234ad65a006243aee60406fa9f8a05c08f0 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Fri, 16 Sep 2011 14:35:39 +0200 Subject: [PATCH] Remove autoderef for calls We were only using it in a single place, and there for no discernable reason (probably as part of the bare-fn-vals-are-not-copyable plan). It seems more surprising than useful. --- src/comp/front/test.rs | 4 ++-- src/comp/middle/alias.rs | 4 ++-- src/comp/middle/mut.rs | 4 +--- src/comp/middle/trans.rs | 11 ++++------- src/comp/middle/typeck.rs | 13 +++---------- src/test/compile-fail/occurs-check-2.rs | 2 -- src/test/run-pass/auto-deref-fn.rs | 10 ---------- src/test/run-pass/call-autoderef-tag.rs | 10 ---------- src/test/run-pass/fixed-point-bind-box.rs | 12 ++++++------ 9 files changed, 18 insertions(+), 52 deletions(-) delete mode 100644 src/test/compile-fail/occurs-check-2.rs delete mode 100644 src/test/run-pass/auto-deref-fn.rs delete mode 100644 src/test/run-pass/call-autoderef-tag.rs diff --git a/src/comp/front/test.rs b/src/comp/front/test.rs index fcc4f883139..44ae6838a81 100644 --- a/src/comp/front/test.rs +++ b/src/comp/front/test.rs @@ -10,7 +10,7 @@ import front::attr; export modify_for_testing; -type node_id_gen = @fn() -> ast::node_id; +type node_id_gen = fn() -> ast::node_id; type test = {path: [ast::ident], ignore: bool}; @@ -29,7 +29,7 @@ fn modify_for_testing(crate: @ast::crate) -> @ast::crate { // access to the real next node_id. let next_node_id = @mutable 200000; let next_node_id_fn = - @bind fn (next_node_id: @mutable ast::node_id) -> ast::node_id { + bind fn (next_node_id: @mutable ast::node_id) -> ast::node_id { let this_node_id = *next_node_id; *next_node_id += 1; ret this_node_id; diff --git a/src/comp/middle/alias.rs b/src/comp/middle/alias.rs index 1c8d15bb74b..f1788fda27e 100644 --- a/src/comp/middle/alias.rs +++ b/src/comp/middle/alias.rs @@ -222,7 +222,7 @@ fn cant_copy(cx: ctx, b: binding) -> bool { } fn check_call(cx: ctx, f: @ast::expr, args: [@ast::expr]) -> [binding] { - let fty = ty::type_autoderef(cx.tcx, ty::expr_ty(cx.tcx, f)); + 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 } }; @@ -685,7 +685,7 @@ fn expr_root(cx: ctx, ex: @ast::expr, autoderef: bool) if is_none(path_def_id(cx, base_root.ex)) { alt base_root.ex.node { ast::expr_call(f, args) { - let fty = ty::type_autoderef(cx.tcx, ty::expr_ty(cx.tcx, f)); + 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]; diff --git a/src/comp/middle/mut.rs b/src/comp/middle/mut.rs index 2d13af25622..8974509a8a9 100644 --- a/src/comp/middle/mut.rs +++ b/src/comp/middle/mut.rs @@ -219,9 +219,7 @@ fn check_move_rhs(cx: @ctx, src: @expr) { } fn check_call(cx: @ctx, f: @expr, args: [@expr]) { - let arg_ts = - ty::ty_fn_args(cx.tcx, - ty::type_autoderef(cx.tcx, ty::expr_ty(cx.tcx, f))); + let arg_ts = ty::ty_fn_args(cx.tcx, ty::expr_ty(cx.tcx, f)); let i = 0u; for arg_t: ty::arg in arg_ts { if arg_t.mode != by_ref { check_lval(cx, args[i], msg_mut_ref); } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 26c20e1c28e..cdcb9917b1d 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -3676,9 +3676,8 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr, // expression because of the hack that allows us to process self-calls // with trans_call. let fn_expr_ty = ty::expr_ty(bcx_tcx(in_cx), f); - let fn_ty = ty::type_autoderef(bcx_tcx(in_cx), fn_expr_ty); let by_ref = ast_util::ret_by_ref(ty::ty_fn_ret_style(bcx_tcx(in_cx), - fn_ty)); + fn_expr_ty)); let cx = new_scope_block_ctxt(in_cx, "call"); let f_res = trans_lval_gen(cx, f); let bcx = f_res.res.bcx; @@ -3694,10 +3693,7 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr, none. { // It's a closure. We have to autoderef. if f_res.is_mem { faddr = load_if_immediate(bcx, faddr, fn_expr_ty); } - let res = autoderef(bcx, faddr, fn_expr_ty); - bcx = res.bcx; - - let pair = res.val; + let pair = faddr; faddr = GEP(bcx, pair, [C_int(0), C_int(abi::fn_field_code)]); faddr = Load(bcx, faddr); let llclosure = GEP(bcx, pair, [C_int(0), C_int(abi::fn_field_box)]); @@ -3707,7 +3703,8 @@ fn trans_call(in_cx: @block_ctxt, f: @ast::expr, let ret_ty = ty::node_id_to_type(bcx_tcx(cx), id); let args_res = - trans_args(bcx, in_cx, llenv, f_res.generic, lliterbody, args, fn_ty); + trans_args(bcx, in_cx, llenv, f_res.generic, lliterbody, args, + fn_expr_ty); Br(args_res.outer_cx, cx.llbb); bcx = args_res.bcx; let llargs = args_res.args; diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 8b321a5753f..ad1d88b35a3 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -1488,14 +1488,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, // Get the function type. let fty = expr_ty(fcx.ccx.tcx, f); - // We want to autoderef calls but not binds - let fty_stripped = - alt call_kind { - kind_call. { do_autoderef(fcx, sp, fty) } - _ { fty } - }; - - let sty = structure_of(fcx, sp, fty_stripped); + let sty = structure_of(fcx, sp, fty); // Check that we aren't confusing iter calls and fn calls alt sty { @@ -1620,14 +1613,14 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, // Pull the return type out of the type of the function. let rt_1; - let fty = do_autoderef(fcx, sp, ty::expr_ty(fcx.ccx.tcx, f)); + let fty = ty::expr_ty(fcx.ccx.tcx, f); alt structure_of(fcx, sp, fty) { ty::ty_fn(_, _, rt, cf, _) { bot |= cf == ast::noreturn; rt_1 = rt; } ty::ty_native_fn(_, _, rt) { rt_1 = rt; } - _ { fail "LHS of call expr didn't have a function type?!"; } + _ { fcx.ccx.tcx.sess.span_fatal(sp, "calling non-function"); } } write::ty_only_fixup(fcx, id, rt_1); ret bot; diff --git a/src/test/compile-fail/occurs-check-2.rs b/src/test/compile-fail/occurs-check-2.rs deleted file mode 100644 index 6c600158d21..00000000000 --- a/src/test/compile-fail/occurs-check-2.rs +++ /dev/null @@ -1,2 +0,0 @@ -// error-pattern: Type inference failed because I could not find -fn main() { let f; f = @f; f(); } diff --git a/src/test/run-pass/auto-deref-fn.rs b/src/test/run-pass/auto-deref-fn.rs deleted file mode 100644 index caff3f29fbc..00000000000 --- a/src/test/run-pass/auto-deref-fn.rs +++ /dev/null @@ -1,10 +0,0 @@ -fn add1(i: int) -> int { ret i + 1; } -fn main() { - let f = @add1; - let g = @f; - let h = @@@add1; - assert (f(5) == 6); - assert (g(8) == 9); - assert (h(0x1badd00d) == 0x1badd00e); - assert ((@add1)(42) == 43); -} diff --git a/src/test/run-pass/call-autoderef-tag.rs b/src/test/run-pass/call-autoderef-tag.rs deleted file mode 100644 index f978092ca95..00000000000 --- a/src/test/run-pass/call-autoderef-tag.rs +++ /dev/null @@ -1,10 +0,0 @@ -tag int_fn { f(fn(int) -> int); } -tag int_box_fn { fb(@fn(int) -> int); } -fn add1(i: int) -> int { ret i + 1; } -fn main() { - let g = f(add1); - assert (g(4) == 5); - assert (f(add1)(5) == 6); - assert ((@f(add1))(5) == 6); - assert (fb(@add1)(7) == 8); -} diff --git a/src/test/run-pass/fixed-point-bind-box.rs b/src/test/run-pass/fixed-point-bind-box.rs index 53f93347c74..dee72f7b097 100644 --- a/src/test/run-pass/fixed-point-bind-box.rs +++ b/src/test/run-pass/fixed-point-bind-box.rs @@ -1,18 +1,18 @@ -fn fix_help(f: @fn(@fn(A) -> B, A) -> B, x: A) -> B { - ret f(@bind fix_help(f, _), x); +fn fix_help(f: fn(fn(A) -> B, A) -> B, x: A) -> B { + ret f(bind fix_help(f, _), x); } -fn fix(f: @fn(@fn(A) -> B, A) -> B) -> @fn(A) -> B { - ret @bind fix_help(f, _); +fn fix(f: fn(fn(A) -> B, A) -> B) -> fn(A) -> B { + ret bind fix_help(f, _); } -fn fact_(f: @fn(int) -> int, n: int) -> int { +fn fact_(f: fn(int) -> int, n: int) -> int { // fun fact 0 = 1 ret if n == 0 { 1 } else { n * f(n - 1) }; } fn main() { - let fact = fix(@fact_); + let fact = fix(fact_); assert (fact(5) == 120); assert (fact(2) == 2); }