diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 42bbbff22cd..7b4acfac4b3 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -1775,7 +1775,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, _attributes: &[ast::Attribute], output_type: ty::FnOutput<'tcx>, abi: Abi, - closure_env: closure::ClosureEnv<'b, 'tcx>) { + closure_env: closure::ClosureEnv<'b>) { ccx.stats().n_closures.set(ccx.stats().n_closures.get() + 1); let _icx = push_ctxt("trans_closure"); @@ -1784,12 +1784,17 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, debug!("trans_closure(..., param_substs={})", param_substs.repr(ccx.tcx())); + let has_env = match closure_env { + closure::ClosureEnv::Closure(_) => true, + closure::ClosureEnv::NotClosure => false, + }; + let (arena, fcx): (TypedArena<_>, FunctionContext); arena = TypedArena::new(); fcx = new_fn_ctxt(ccx, llfndecl, fn_ast_id, - closure_env.kind != closure::ClosureKind::NotClosure, + has_env, output_type, param_substs, Some(body.span), @@ -1808,13 +1813,13 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, decl.inputs.iter() .map(|arg| node_id_type(bcx, arg.id)) .collect::>(); - let monomorphized_arg_types = match closure_env.kind { - closure::ClosureKind::NotClosure => { + let monomorphized_arg_types = match closure_env { + closure::ClosureEnv::NotClosure => { monomorphized_arg_types } // Tuple up closure argument types for the "rust-call" ABI. - closure::ClosureKind::Closure => { + closure::ClosureEnv::Closure(_) => { vec![ty::mk_tup(ccx.tcx(), monomorphized_arg_types)] } }; @@ -1835,14 +1840,14 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>, &monomorphized_arg_types[]) }; - bcx = match closure_env.kind { - closure::ClosureKind::NotClosure => { + bcx = match closure_env { + closure::ClosureEnv::NotClosure => { copy_args_to_allocas(bcx, arg_scope, &decl.inputs[], arg_datums) } - closure::ClosureKind::Closure => { + closure::ClosureEnv::Closure(_) => { copy_closure_args_to_allocas( bcx, arg_scope, @@ -1932,7 +1937,7 @@ pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, attrs, output_type, abi, - closure::ClosureEnv::new(&[], closure::ClosureKind::NotClosure)); + closure::ClosureEnv::NotClosure); } pub fn trans_enum_variant<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index 99ae0dc1007..a15ede095a7 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -97,37 +97,23 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, bcx } -#[derive(PartialEq)] -pub enum ClosureKind<'tcx> { +pub enum ClosureEnv<'a> { NotClosure, - Closure, + Closure(&'a [ty::Freevar]), } -pub struct ClosureEnv<'a, 'tcx> { - freevars: &'a [ty::Freevar], - pub kind: ClosureKind<'tcx> -} - -impl<'a, 'tcx> ClosureEnv<'a, 'tcx> { - pub fn new(freevars: &'a [ty::Freevar], kind: ClosureKind<'tcx>) - -> ClosureEnv<'a, 'tcx> { - ClosureEnv { - freevars: freevars, - kind: kind - } - } - - pub fn load<'blk>(self, bcx: Block<'blk, 'tcx>, arg_scope: ScopeId) - -> Block<'blk, 'tcx> { - // Don't bother to create the block if there's nothing to load - if self.freevars.is_empty() { - return bcx; - } - - match self.kind { - ClosureKind::NotClosure => bcx, - ClosureKind::Closure => { - load_closure_environment(bcx, arg_scope, self.freevars) +impl<'a> ClosureEnv<'a> { + pub fn load<'blk,'tcx>(self, bcx: Block<'blk, 'tcx>, arg_scope: ScopeId) + -> Block<'blk, 'tcx> + { + match self { + ClosureEnv::NotClosure => bcx, + ClosureEnv::Closure(freevars) => { + if freevars.is_empty() { + bcx + } else { + load_closure_environment(bcx, arg_scope, freevars) + } } } } @@ -224,7 +210,7 @@ pub fn trans_closure_expr<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, &[], sig.output, function_type.abi, - ClosureEnv::new(&freevars[], ClosureKind::Closure)); + ClosureEnv::Closure(&freevars[])); // Don't hoist this to the top of the function. It's perfectly legitimate // to have a zero-size closure (in which case dest will be `Ignore`) and