diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 0ed6ae31171..c52f31532dc 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -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(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); diff --git a/src/librustc_trans/save/mod.rs b/src/librustc_trans/save/mod.rs index 2a698a898fe..329241b24e6 100644 --- a/src/librustc_trans/save/mod.rs +++ b/src/librustc_trans/save/mod.rs @@ -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(&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); diff --git a/src/librustc_trans/trans/_match.rs b/src/librustc_trans/trans/_match.rs index 7a7a708fcc5..b0512925719 100644 --- a/src/librustc_trans/trans/_match.rs +++ b/src/librustc_trans/trans/_match.rs @@ -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. diff --git a/src/librustc_trans/trans/adt.rs b/src/librustc_trans/trans/adt.rs index e273a56ce02..991333d8f07 100644 --- a/src/librustc_trans/trans/adt.rs +++ b/src/librustc_trans/trans/adt.rs @@ -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, _) => { diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index cef12616cf2..5170746404e 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -107,9 +107,11 @@ thread_local!(static TASK_LOCAL_INSN_KEY: RefCell>> = { 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(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(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"); diff --git a/src/librustc_trans/trans/cabi_x86_64.rs b/src/librustc_trans/trans/cabi_x86_64.rs index 00c91ddebb3..4a6bc58051c 100644 --- a/src/librustc_trans/trans/cabi_x86_64.rs +++ b/src/librustc_trans/trans/cabi_x86_64.rs @@ -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(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()) { diff --git a/src/librustc_trans/trans/callee.rs b/src/librustc_trans/trans/callee.rs index ff7ab91c39a..b8b2395dde1 100644 --- a/src/librustc_trans/trans/callee.rs +++ b/src/librustc_trans/trans/callee.rs @@ -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, - callee_ty: Ty<'tcx>, - get_callee: |bcx: Block<'blk, 'tcx>, - arg_cleanup_scope: cleanup::ScopeId| - -> Callee<'blk, 'tcx>, - args: CallArgs<'a, 'tcx>, - dest: Option) - -> Result<'blk, 'tcx> { +pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, + call_info: Option, + callee_ty: Ty<'tcx>, + get_callee: F, + args: CallArgs<'a, 'tcx>, + dest: Option) + -> 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 diff --git a/src/librustc_trans/trans/cleanup.rs b/src/librustc_trans/trans/cleanup.rs index ba3e70fe036..2fd6551409e 100644 --- a/src/librustc_trans/trans/cleanup.rs +++ b/src/librustc_trans/trans/cleanup.rs @@ -527,7 +527,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx self.scopes.borrow_mut().pop().unwrap() } - fn top_scope(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R { + fn top_scope(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R { f(self.scopes.borrow().last().unwrap()) } @@ -1145,5 +1145,5 @@ trait CleanupHelperMethods<'blk, 'tcx> { fn scopes_len(&self) -> uint; fn push_scope(&self, scope: CleanupScope<'blk, 'tcx>); fn pop_scope(&self) -> CleanupScope<'blk, 'tcx>; - fn top_scope(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R; + fn top_scope(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R; } diff --git a/src/librustc_trans/trans/datum.rs b/src/librustc_trans/trans/datum.rs index edcc8edaf7f..531b22c8fb5 100644 --- a/src/librustc_trans/trans/datum.rs +++ b/src/librustc_trans/trans/datum.rs @@ -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 @@ impl<'tcx> Datum<'tcx, Rvalue> { /// here since we can `match self.kind` rather than having to implement /// generic methods in `KindOps`.) impl<'tcx> Datum<'tcx, Expr> { - fn match_kind(self, - if_lvalue: |Datum<'tcx, Lvalue>| -> R, - if_rvalue: |Datum<'tcx, Rvalue>| -> R) - -> R { + fn match_kind(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 @@ impl<'tcx> Datum<'tcx, Lvalue> { // 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(_) => { diff --git a/src/librustc_trans/trans/debuginfo.rs b/src/librustc_trans/trans/debuginfo.rs index f6c4ba64576..de169fc9d62 100644 --- a/src/librustc_trans/trans/debuginfo.rs +++ b/src/librustc_trans/trans/debuginfo.rs @@ -3212,13 +3212,13 @@ fn populate_scope_map(cx: &CrateContext, }); // local helper functions for walking the AST. - fn with_new_scope(cx: &CrateContext, - scope_span: Span, - scope_stack: &mut Vec , - scope_map: &mut NodeMap, - inner_walk: |&CrateContext, - &mut Vec , - &mut NodeMap|) { + fn with_new_scope(cx: &CrateContext, + scope_span: Span, + scope_stack: &mut Vec , + scope_map: &mut NodeMap, + inner_walk: F) where + F: FnOnce(&CrateContext, &mut Vec, &mut NodeMap), + { // 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()); diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index e3e6fff7234..e1769001942 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -295,6 +295,7 @@ fn apply_adjustments<'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), 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 apply_adjustments<'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 apply_adjustments<'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, - 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, + 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())