about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMark Simulacrum <mark.simulacrum@gmail.com>2016-12-19 17:39:14 -0700
committerMark Simulacrum <mark.simulacrum@gmail.com>2016-12-20 20:04:42 -0700
commit15c9e5e35bc3a9675c476ae10eb656df2c2c14ed (patch)
tree7c821af2e03988cbae9baa44fff5608e73a89951
parent88202c5b838ea9f328d37f19c022eba5040e234f (diff)
downloadrust-15c9e5e35bc3a9675c476ae10eb656df2c2c14ed.tar.gz
rust-15c9e5e35bc3a9675c476ae10eb656df2c2c14ed.zip
Mutate llargs instead of reconstructing it.
-rw-r--r--src/librustc_trans/callee.rs34
1 files changed, 14 insertions, 20 deletions
diff --git a/src/librustc_trans/callee.rs b/src/librustc_trans/callee.rs
index 384c70ffa44..44e94a1dfe3 100644
--- a/src/librustc_trans/callee.rs
+++ b/src/librustc_trans/callee.rs
@@ -331,16 +331,21 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
     let fcx = FunctionContext::new(ccx, lloncefn, fn_ty);
     let mut bcx = fcx.get_entry_block();
 
+    let callee = Callee {
+        data: Fn(llreffn),
+        ty: llref_fn_ty
+    };
+
     // the first argument (`self`) will be the (by value) closure env.
 
     let mut llargs = get_params(fcx.llfn);
-    let mut self_idx = fcx.fn_ty.ret.is_indirect() as usize;
+    let idx = fcx.fn_ty.ret.is_indirect() as usize;
     let env_arg = &fcx.fn_ty.args[0];
     let llenv = if env_arg.is_indirect() {
-        llargs[self_idx]
+        llargs[idx]
     } else {
         let scratch = alloc_ty(&bcx, closure_ty, "self");
-        let mut llarg_idx = self_idx;
+        let mut llarg_idx = idx;
         env_arg.store_fn_arg(&bcx, &mut llarg_idx, scratch);
         scratch
     };
@@ -349,35 +354,24 @@ fn trans_fn_once_adapter_shim<'a, 'tcx>(
     // Adjust llargs such that llargs[self_idx..] has the call arguments.
     // For zero-sized closures that means sneaking in a new argument.
     if env_arg.is_ignore() {
-        if self_idx > 0 {
-            self_idx -= 1;
-            llargs[self_idx] = llenv;
+        if fcx.fn_ty.ret.is_indirect() {
+            llargs[0] = llenv;
         } else {
             llargs.insert(0, llenv);
         }
     } else {
-        llargs[self_idx] = llenv;
+        llargs[idx] = llenv;
     }
 
-    let callee = Callee {
-        data: Fn(llreffn),
-        ty: llref_fn_ty
-    };
-
     // Call the by-ref closure body with `self` in a cleanup scope,
     // to drop `self` when the body returns, or in case it unwinds.
     let self_scope = fcx.schedule_drop_mem(llenv, closure_ty);
     let fn_ret = callee.ty.fn_ret();
     let fn_ty = callee.direct_fn_type(bcx.ccx, &[]);
 
-    let first_llarg = if fn_ty.ret.is_indirect() && !fcx.fn_ty.ret.is_ignore() {
-        Some(get_param(fcx.llfn, 0))
-    } else {
-        None
-    };
-    let llargs = first_llarg.into_iter().chain(llargs[self_idx..].iter().cloned())
-        .collect::<Vec<_>>();
-
+    if fn_ty.ret.is_indirect() {
+        llargs.insert(0, get_param(fcx.llfn, 0));
+    }
     let llfn = callee.reify(bcx.ccx);
     let llret;
     if let Some(landing_pad) = self_scope.landing_pad {