// 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);
}
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);
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.
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, _) => {
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()));
})
}
|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) {
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");
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()) {
///
/// 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
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())
}
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;
}
/// 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 {
/// 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)),
// 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(_) => {
});
// 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());
// 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,
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>,
-> 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
}
}
-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,
/// 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())