]> git.lizzy.rs Git - rust.git/commitdiff
librustc_trans: use unboxed closures
authorJorge Aparicio <japaricious@gmail.com>
Tue, 9 Dec 2014 18:44:51 +0000 (13:44 -0500)
committerJorge Aparicio <japaricious@gmail.com>
Sat, 13 Dec 2014 22:03:48 +0000 (17:03 -0500)
src/librustc_trans/back/write.rs
src/librustc_trans/save/mod.rs
src/librustc_trans/trans/_match.rs
src/librustc_trans/trans/adt.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/cabi_x86_64.rs
src/librustc_trans/trans/callee.rs
src/librustc_trans/trans/cleanup.rs
src/librustc_trans/trans/datum.rs
src/librustc_trans/trans/debuginfo.rs
src/librustc_trans/trans/expr.rs

index 0ed6ae311711fc747b79cd4ddbcdb1f37a5138da..c52f31532dcd0c63c74ab4dfe8367ab41f854194 100644 (file)
@@ -488,8 +488,12 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
     // pass manager passed to the closure should be ensured to not
     // escape the closure itself, and the manager should only be
     // used once.
-    unsafe fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef,
-                    no_builtins: bool, f: |PassManagerRef|) {
+    unsafe fn with_codegen<F>(tm: TargetMachineRef,
+                              llmod: ModuleRef,
+                              no_builtins: bool,
+                              f: F) where
+        F: FnOnce(PassManagerRef),
+    {
         let cpm = llvm::LLVMCreatePassManager();
         llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
         llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
index 2a698a898fe871a91d390def4097447100eafc28..329241b24e6520f0fa3d5daa4db8a60a674371d8 100644 (file)
@@ -79,7 +79,9 @@ struct DxrVisitor<'l, 'tcx: 'l> {
 }
 
 impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
-    fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) {
+    fn nest<F>(&mut self, scope_id: NodeId, f: F) where
+        F: FnOnce(&mut DxrVisitor<'l, 'tcx>),
+    {
         let parent_scope = self.cur_scope;
         self.cur_scope = scope_id;
         f(self);
index 7a7a708fcc509830f404f5b20f43e9a82f19e688..b051292571980fe47987f7cdf79ed9c75a00d0d0 100644 (file)
@@ -1578,14 +1578,15 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     bind_irrefutable_pat(bcx, pat, llvalue, body_scope)
 }
 
-fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
-                                    p_id: ast::NodeId,
-                                    ident: &ast::Ident,
-                                    cleanup_scope: cleanup::ScopeId,
-                                    arg: A,
-                                    populate: |A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>|
-                                              -> Block<'blk, 'tcx>)
-                                    -> Block<'blk, 'tcx> {
+fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
+                                       p_id: ast::NodeId,
+                                       ident: &ast::Ident,
+                                       cleanup_scope: cleanup::ScopeId,
+                                       arg: A,
+                                       populate: F)
+                                       -> Block<'blk, 'tcx> where
+    F: FnOnce(A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
+{
     let var_ty = node_id_type(bcx, p_id);
 
     // Allocate memory on stack for the binding.
index e273a56ce025b2b33f616b4f63cbde4373ab833a..991333d8f07ddb9a9b4d97b27058641783a2952a 100644 (file)
@@ -858,10 +858,13 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
     GEPi(bcx, val, &[0, ix])
 }
 
-pub fn fold_variants<'blk, 'tcx>(
-        bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, value: ValueRef,
-        f: |Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef| -> Block<'blk, 'tcx>)
-        -> Block<'blk, 'tcx> {
+pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                    r: &Repr<'tcx>,
+                                    value: ValueRef,
+                                    mut f: F)
+                                    -> Block<'blk, 'tcx> where
+    F: FnMut(Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef) -> Block<'blk, 'tcx>,
+{
     let fcx = bcx.fcx;
     match *r {
         Univariant(ref st, _) => {
index cef12616cf267178b2301fc5c196488ffdd02afc..5170746404e01d0a440c57aa6258e5bc53031f7a 100644 (file)
     RefCell::new(None)
 })
 
-pub fn with_insn_ctxt(blk: |&[&'static str]|) {
-    TASK_LOCAL_INSN_KEY.with(|slot| {
-        slot.borrow().as_ref().map(|s| blk(s.as_slice()));
+pub fn with_insn_ctxt<F>(blk: F) where
+    F: FnOnce(&[&'static str]),
+{
+    TASK_LOCAL_INSN_KEY.with(move |slot| {
+        slot.borrow().as_ref().map(move |s| blk(s.as_slice()));
     })
 }
 
@@ -841,12 +843,15 @@ pub fn cast_shift_const_rhs(op: ast::BinOp,
                    |a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) })
 }
 
-pub fn cast_shift_rhs(op: ast::BinOp,
-                      lhs: ValueRef,
-                      rhs: ValueRef,
-                      trunc: |ValueRef, Type| -> ValueRef,
-                      zext: |ValueRef, Type| -> ValueRef)
-                      -> ValueRef {
+pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
+                            lhs: ValueRef,
+                            rhs: ValueRef,
+                            trunc: F,
+                            zext: G)
+                            -> ValueRef where
+    F: FnOnce(ValueRef, Type) -> ValueRef,
+    G: FnOnce(ValueRef, Type) -> ValueRef,
+{
     // Shifts may have any size int on the rhs
     unsafe {
         if ast_util::is_shift_binop(op) {
@@ -1101,10 +1106,12 @@ pub fn raw_block<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
     common::BlockS::new(llbb, is_lpad, None, fcx)
 }
 
-pub fn with_cond<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                             val: ValueRef,
-                             f: |Block<'blk, 'tcx>| -> Block<'blk, 'tcx>)
-                             -> Block<'blk, 'tcx> {
+pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                val: ValueRef,
+                                f: F)
+                                -> Block<'blk, 'tcx> where
+    F: FnOnce(Block<'blk, 'tcx>) -> Block<'blk, 'tcx>,
+{
     let _icx = push_ctxt("with_cond");
     let fcx = bcx.fcx;
     let next_cx = fcx.new_temp_block("next");
index 00c91ddebb38ebf31331f1974d1f0bbbd534c95e..4a6bc58051c57aa9b4132d56b332c0d9c2d2c690 100644 (file)
@@ -342,11 +342,13 @@ pub fn compute_abi_info(ccx: &CrateContext,
                         atys: &[Type],
                         rty: Type,
                         ret_def: bool) -> FnType {
-    fn x86_64_ty(ccx: &CrateContext,
-                 ty: Type,
-                 is_mem_cls: |cls: &[RegClass]| -> bool,
-                 ind_attr: Attribute)
-                 -> ArgType {
+    fn x86_64_ty<F>(ccx: &CrateContext,
+                    ty: Type,
+                    is_mem_cls: F,
+                    ind_attr: Attribute)
+                    -> ArgType where
+        F: FnOnce(&[RegClass]) -> bool,
+    {
         if !ty.is_reg_ty() {
             let cls = classify_ty(ty);
             if is_mem_cls(cls.as_slice()) {
index ff7ab91c39a58edbecc42b4d0466b96eb97937fa..b8b2395dde17229225bbe45ec1dc4a77f24d45a1 100644 (file)
@@ -781,15 +781,15 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 ///
 /// For non-lang items, `dest` is always Some, and hence the result is written into memory
 /// somewhere. Nonetheless we return the actual return value of the function.
-pub fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                        call_info: Option<NodeInfo>,
-                                        callee_ty: Ty<'tcx>,
-                                        get_callee: |bcx: Block<'blk, 'tcx>,
-                                                     arg_cleanup_scope: cleanup::ScopeId|
-                                                     -> Callee<'blk, 'tcx>,
-                                        args: CallArgs<'a, 'tcx>,
-                                        dest: Option<expr::Dest>)
-                                        -> Result<'blk, 'tcx> {
+pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                                           call_info: Option<NodeInfo>,
+                                           callee_ty: Ty<'tcx>,
+                                           get_callee: F,
+                                           args: CallArgs<'a, 'tcx>,
+                                           dest: Option<expr::Dest>)
+                                           -> Result<'blk, 'tcx> where
+    F: FnOnce(Block<'blk, 'tcx>, cleanup::ScopeId) -> Callee<'blk, 'tcx>,
+{
     // Introduce a temporary cleanup scope that will contain cleanups
     // for the arguments while they are being evaluated. The purpose
     // this cleanup is to ensure that, should a panic occur while
index ba3e70fe036fc475720784055f64b2c34b82cf23..2fd6551409e90e734f288039805cd98862820da0 100644 (file)
@@ -527,7 +527,7 @@ fn pop_scope(&self) -> CleanupScope<'blk, 'tcx> {
         self.scopes.borrow_mut().pop().unwrap()
     }
 
-    fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R {
+    fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R {
         f(self.scopes.borrow().last().unwrap())
     }
 
@@ -1145,5 +1145,5 @@ fn trans_cleanups_to_exit_scope(&'blk self,
     fn scopes_len(&self) -> uint;
     fn push_scope(&self, scope: CleanupScope<'blk, 'tcx>);
     fn pop_scope(&self) -> CleanupScope<'blk, 'tcx>;
-    fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R;
+    fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R;
 }
index edcc8edaf7f92da65d59af8a933bbc154edad27f..531b22c8fb5f2d221c0757c8d2ad1fe7ea8c3f53 100644 (file)
@@ -113,15 +113,16 @@ pub fn immediate_rvalue_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// it. The memory will be dropped upon exit from `scope`. The callback `populate` should
 /// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this
 /// is not necessary unless `bcx` does not dominate the end of `scope`.
-pub fn lvalue_scratch_datum<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
-                                           ty: Ty<'tcx>,
-                                           name: &str,
-                                           zero: bool,
-                                           scope: cleanup::ScopeId,
-                                           arg: A,
-                                           populate: |A, Block<'blk, 'tcx>, ValueRef|
-                                                      -> Block<'blk, 'tcx>)
-                                          -> DatumBlock<'blk, 'tcx, Lvalue> {
+pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
+                                              ty: Ty<'tcx>,
+                                              name: &str,
+                                              zero: bool,
+                                              scope: cleanup::ScopeId,
+                                              arg: A,
+                                              populate: F)
+                                              -> DatumBlock<'blk, 'tcx, Lvalue> where
+    F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>,
+{
     let scratch = if zero {
         alloca_zeroed(bcx, ty, name)
     } else {
@@ -339,10 +340,10 @@ pub fn to_appropriate_datum<'blk>(self, bcx: Block<'blk, 'tcx>)
 /// here since we can `match self.kind` rather than having to implement
 /// generic methods in `KindOps`.)
 impl<'tcx> Datum<'tcx, Expr> {
-    fn match_kind<R>(self,
-                     if_lvalue: |Datum<'tcx, Lvalue>| -> R,
-                     if_rvalue: |Datum<'tcx, Rvalue>| -> R)
-                     -> R {
+    fn match_kind<R, F, G>(self, if_lvalue: F, if_rvalue: G) -> R where
+        F: FnOnce(Datum<'tcx, Lvalue>) -> R,
+        G: FnOnce(Datum<'tcx, Rvalue>) -> R,
+    {
         let Datum { val, ty, kind } = self;
         match kind {
             LvalueExpr => if_lvalue(Datum::new(val, ty, Lvalue)),
@@ -455,9 +456,11 @@ pub fn to_llref(self) -> ValueRef {
     // datum may also be unsized _without the size information_. It is the
     // callers responsibility to package the result in some way to make a valid
     // datum in that case (e.g., by making a fat pointer or opened pair).
-    pub fn get_element<'blk>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
-                             gep: |ValueRef| -> ValueRef)
-                             -> Datum<'tcx, Lvalue> {
+    pub fn get_element<'blk, F>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
+                                gep: F)
+                                -> Datum<'tcx, Lvalue> where
+        F: FnOnce(ValueRef) -> ValueRef,
+    {
         let val = match self.ty.sty {
             _ if ty::type_is_sized(bcx.tcx(), self.ty) => gep(self.val),
             ty::ty_open(_) => {
index f6c4ba64576f76d656efae22d1a556861501fffb..de169fc9d62a6f2f67e92beac98b4e73b94e137c 100644 (file)
@@ -3212,13 +3212,13 @@ struct ScopeStackEntry {
     });
 
     // local helper functions for walking the AST.
-    fn with_new_scope(cx: &CrateContext,
-                      scope_span: Span,
-                      scope_stack: &mut Vec<ScopeStackEntry> ,
-                      scope_map: &mut NodeMap<DIScope>,
-                      inner_walk: |&CrateContext,
-                                   &mut Vec<ScopeStackEntry> ,
-                                   &mut NodeMap<DIScope>|) {
+    fn with_new_scope<F>(cx: &CrateContext,
+                         scope_span: Span,
+                         scope_stack: &mut Vec<ScopeStackEntry> ,
+                         scope_map: &mut NodeMap<DIScope>,
+                         inner_walk: F) where
+        F: FnOnce(&CrateContext, &mut Vec<ScopeStackEntry>, &mut NodeMap<DIScope>),
+    {
         // Create a new lexical scope and push it onto the stack
         let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
         let file_metadata = file_metadata(cx, loc.file.name.as_slice());
index e3e6fff723410ad29d4caacd8028aacaa59b2b01..e1769001942d586950358355618d518603289fed 100644 (file)
@@ -295,6 +295,7 @@ fn ref_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     // into a type to be destructed. If we want to end up with a Box pointer,
     // then mk_ty should make a Box pointer (T -> Box<T>), if we want a
     // borrowed reference then it should be T -> &T.
+    // FIXME(#19596) unbox `mk_ty`
     fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                 kind: &ty::UnsizeKind<'tcx>,
                                 id: ast::NodeId,
@@ -341,27 +342,30 @@ fn unsize_expr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
         debug!("dest_ty={}", unsized_ty.repr(bcx.tcx()));
         // Closures for extracting and manipulating the data and payload parts of
         // the fat pointer.
-        let base = match k {
-            &ty::UnsizeStruct(..) =>
-                |bcx, val| PointerCast(bcx,
-                                       val,
-                                       type_of::type_of(bcx.ccx(), unsized_ty).ptr_to()),
-            &ty::UnsizeLength(..) =>
-                |bcx, val| GEPi(bcx, val, &[0u, 0u]),
-            &ty::UnsizeVtable(..) =>
-                |_bcx, val| PointerCast(bcx, val, Type::i8p(bcx.ccx()))
-        };
-        let info = |bcx, _val| unsized_info(bcx,
-                                            k,
-                                            expr.id,
-                                            datum_ty,
-                                            |t| ty::mk_rptr(tcx,
-                                                            ty::ReStatic,
-                                                            ty::mt{
-                                                                ty: t,
-                                                                mutbl: ast::MutImmutable
-                                                            }));
-        into_fat_ptr(bcx, expr, datum, dest_ty, base, info)
+        let info = |: bcx, _val| unsized_info(bcx,
+                                              k,
+                                              expr.id,
+                                              datum_ty,
+                                              |t| ty::mk_rptr(tcx,
+                                                              ty::ReStatic,
+                                                              ty::mt{
+                                                                  ty: t,
+                                                                  mutbl: ast::MutImmutable
+                                                              }));
+        match *k {
+            ty::UnsizeStruct(..) =>
+                into_fat_ptr(bcx, expr, datum, dest_ty, |bcx, val| {
+                    PointerCast(bcx, val, type_of::type_of(bcx.ccx(), unsized_ty).ptr_to())
+                }, info),
+            ty::UnsizeLength(..) =>
+                into_fat_ptr(bcx, expr, datum, dest_ty, |bcx, val| {
+                    GEPi(bcx, val, &[0u, 0u])
+                }, info),
+            ty::UnsizeVtable(..) =>
+                into_fat_ptr(bcx, expr, datum, dest_ty, |_bcx, val| {
+                    PointerCast(bcx, val, Type::i8p(bcx.ccx()))
+                }, info),
+        }
     }
 
     fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@@ -370,18 +374,21 @@ fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
                                -> DatumBlock<'blk, 'tcx, Expr> {
         let tcx = bcx.tcx();
         let dest_ty = ty::close_type(tcx, datum.ty);
-        let base = |bcx, val| Load(bcx, get_dataptr(bcx, val));
-        let len = |bcx, val| Load(bcx, get_len(bcx, val));
+        let base = |bcx, val| Load(bcx, get_dataptr(bcx, val));
+        let len = |bcx, val| Load(bcx, get_len(bcx, val));
         into_fat_ptr(bcx, expr, datum, dest_ty, base, len)
     }
 
-    fn into_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                                expr: &ast::Expr,
-                                datum: Datum<'tcx, Expr>,
-                                dest_ty: Ty<'tcx>,
-                                base: |Block<'blk, 'tcx>, ValueRef| -> ValueRef,
-                                info: |Block<'blk, 'tcx>, ValueRef| -> ValueRef)
-                                -> DatumBlock<'blk, 'tcx, Expr> {
+    fn into_fat_ptr<'blk, 'tcx, F, G>(bcx: Block<'blk, 'tcx>,
+                                      expr: &ast::Expr,
+                                      datum: Datum<'tcx, Expr>,
+                                      dest_ty: Ty<'tcx>,
+                                      base: F,
+                                      info: G)
+                                      -> DatumBlock<'blk, 'tcx, Expr> where
+        F: FnOnce(Block<'blk, 'tcx>, ValueRef) -> ValueRef,
+        G: FnOnce(Block<'blk, 'tcx>, ValueRef) -> ValueRef,
+    {
         let mut bcx = bcx;
 
         // Arrange cleanup
@@ -659,17 +666,19 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     }
 }
 
-fn trans_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
-                           base: &ast::Expr,
-                           get_idx: |&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]| -> uint)
-                           -> DatumBlock<'blk, 'tcx, Expr> {
+fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
+                              base: &ast::Expr,
+                              get_idx: F)
+                              -> DatumBlock<'blk, 'tcx, Expr> where
+    F: FnOnce(&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]) -> uint,
+{
     let mut bcx = bcx;
     let _icx = push_ctxt("trans_rec_field");
 
     let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "field"));
     let bare_ty = ty::unopen_type(base_datum.ty);
     let repr = adt::represent_type(bcx.ccx(), bare_ty);
-    with_field_tys(bcx.tcx(), bare_ty, None, |discr, field_tys| {
+    with_field_tys(bcx.tcx(), bare_ty, None, move |discr, field_tys| {
         let ix = get_idx(bcx.tcx(), field_tys);
         let d = base_datum.get_element(
             bcx,
@@ -1254,11 +1263,13 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 /// Helper for enumerating the field types of structs, enums, or records. The optional node ID here
 /// is the node ID of the path identifying the enum variant in use. If none, this cannot possibly
 /// an enum variant (so, if it is and `node_id_opt` is none, this function panics).
-pub fn with_field_tys<'tcx, R>(tcx: &ty::ctxt<'tcx>,
-                               ty: Ty<'tcx>,
-                               node_id_opt: Option<ast::NodeId>,
-                               op: |ty::Disr, (&[ty::field<'tcx>])| -> R)
-                               -> R {
+pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
+                                  ty: Ty<'tcx>,
+                                  node_id_opt: Option<ast::NodeId>,
+                                  op: F)
+                                  -> R where
+    F: FnOnce(ty::Disr, &[ty::field<'tcx>]) -> R,
+{
     match ty.sty {
         ty::ty_struct(did, ref substs) => {
             op(0, struct_fields(tcx, did, substs).as_slice())