diff options
| author | Mark Simulacrum <mark.simulacrum@gmail.com> | 2016-12-19 17:39:14 -0700 |
|---|---|---|
| committer | Mark Simulacrum <mark.simulacrum@gmail.com> | 2016-12-20 20:04:42 -0700 |
| commit | 15c9e5e35bc3a9675c476ae10eb656df2c2c14ed (patch) | |
| tree | 7c821af2e03988cbae9baa44fff5608e73a89951 | |
| parent | 88202c5b838ea9f328d37f19c022eba5040e234f (diff) | |
| download | rust-15c9e5e35bc3a9675c476ae10eb656df2c2c14ed.tar.gz rust-15c9e5e35bc3a9675c476ae10eb656df2c2c14ed.zip | |
Mutate llargs instead of reconstructing it.
| -rw-r--r-- | src/librustc_trans/callee.rs | 34 |
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 { |
