Skip to content

Commit 0676c3b

Browse files
author
Jorge Aparicio
committed
librustc_trans: use unboxed closures
1 parent 0d4d8b9 commit 0676c3b

File tree

11 files changed

+140
-107
lines changed

11 files changed

+140
-107
lines changed

src/librustc_trans/back/write.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,8 +488,12 @@ unsafe fn optimize_and_codegen(cgcx: &CodegenContext,
488488
// pass manager passed to the closure should be ensured to not
489489
// escape the closure itself, and the manager should only be
490490
// used once.
491-
unsafe fn with_codegen(tm: TargetMachineRef, llmod: ModuleRef,
492-
no_builtins: bool, f: |PassManagerRef|) {
491+
unsafe fn with_codegen<F>(tm: TargetMachineRef,
492+
llmod: ModuleRef,
493+
no_builtins: bool,
494+
f: F) where
495+
F: FnOnce(PassManagerRef),
496+
{
493497
let cpm = llvm::LLVMCreatePassManager();
494498
llvm::LLVMRustAddAnalysisPasses(tm, cpm, llmod);
495499
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);

src/librustc_trans/save/mod.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ struct DxrVisitor<'l, 'tcx: 'l> {
7979
}
8080

8181
impl <'l, 'tcx> DxrVisitor<'l, 'tcx> {
82-
fn nest(&mut self, scope_id: NodeId, f: |&mut DxrVisitor<'l, 'tcx>|) {
82+
fn nest<F>(&mut self, scope_id: NodeId, f: F) where
83+
F: FnOnce(&mut DxrVisitor<'l, 'tcx>),
84+
{
8385
let parent_scope = self.cur_scope;
8486
self.cur_scope = scope_id;
8587
f(self);

src/librustc_trans/trans/_match.rs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1578,14 +1578,15 @@ pub fn store_for_loop_binding<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
15781578
bind_irrefutable_pat(bcx, pat, llvalue, body_scope)
15791579
}
15801580

1581-
fn mk_binding_alloca<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
1582-
p_id: ast::NodeId,
1583-
ident: &ast::Ident,
1584-
cleanup_scope: cleanup::ScopeId,
1585-
arg: A,
1586-
populate: |A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>|
1587-
-> Block<'blk, 'tcx>)
1588-
-> Block<'blk, 'tcx> {
1581+
fn mk_binding_alloca<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
1582+
p_id: ast::NodeId,
1583+
ident: &ast::Ident,
1584+
cleanup_scope: cleanup::ScopeId,
1585+
arg: A,
1586+
populate: F)
1587+
-> Block<'blk, 'tcx> where
1588+
F: FnOnce(A, Block<'blk, 'tcx>, ValueRef, Ty<'tcx>) -> Block<'blk, 'tcx>,
1589+
{
15891590
let var_ty = node_id_type(bcx, p_id);
15901591

15911592
// Allocate memory on stack for the binding.

src/librustc_trans/trans/adt.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -858,10 +858,13 @@ pub fn struct_field_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, st: &Struct<'tcx>, v
858858
GEPi(bcx, val, &[0, ix])
859859
}
860860

861-
pub fn fold_variants<'blk, 'tcx>(
862-
bcx: Block<'blk, 'tcx>, r: &Repr<'tcx>, value: ValueRef,
863-
f: |Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef| -> Block<'blk, 'tcx>)
864-
-> Block<'blk, 'tcx> {
861+
pub fn fold_variants<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
862+
r: &Repr<'tcx>,
863+
value: ValueRef,
864+
mut f: F)
865+
-> Block<'blk, 'tcx> where
866+
F: FnMut(Block<'blk, 'tcx>, &Struct<'tcx>, ValueRef) -> Block<'blk, 'tcx>,
867+
{
865868
let fcx = bcx.fcx;
866869
match *r {
867870
Univariant(ref st, _) => {

src/librustc_trans/trans/base.rs

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -107,9 +107,11 @@ thread_local!(static TASK_LOCAL_INSN_KEY: RefCell<Option<Vec<&'static str>>> = {
107107
RefCell::new(None)
108108
})
109109

110-
pub fn with_insn_ctxt(blk: |&[&'static str]|) {
111-
TASK_LOCAL_INSN_KEY.with(|slot| {
112-
slot.borrow().as_ref().map(|s| blk(s.as_slice()));
110+
pub fn with_insn_ctxt<F>(blk: F) where
111+
F: FnOnce(&[&'static str]),
112+
{
113+
TASK_LOCAL_INSN_KEY.with(move |slot| {
114+
slot.borrow().as_ref().map(move |s| blk(s.as_slice()));
113115
})
114116
}
115117

@@ -841,12 +843,15 @@ pub fn cast_shift_const_rhs(op: ast::BinOp,
841843
|a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) })
842844
}
843845

844-
pub fn cast_shift_rhs(op: ast::BinOp,
845-
lhs: ValueRef,
846-
rhs: ValueRef,
847-
trunc: |ValueRef, Type| -> ValueRef,
848-
zext: |ValueRef, Type| -> ValueRef)
849-
-> ValueRef {
846+
pub fn cast_shift_rhs<F, G>(op: ast::BinOp,
847+
lhs: ValueRef,
848+
rhs: ValueRef,
849+
trunc: F,
850+
zext: G)
851+
-> ValueRef where
852+
F: FnOnce(ValueRef, Type) -> ValueRef,
853+
G: FnOnce(ValueRef, Type) -> ValueRef,
854+
{
850855
// Shifts may have any size int on the rhs
851856
unsafe {
852857
if ast_util::is_shift_binop(op) {
@@ -1101,10 +1106,12 @@ pub fn raw_block<'blk, 'tcx>(fcx: &'blk FunctionContext<'blk, 'tcx>,
11011106
common::BlockS::new(llbb, is_lpad, None, fcx)
11021107
}
11031108

1104-
pub fn with_cond<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
1105-
val: ValueRef,
1106-
f: |Block<'blk, 'tcx>| -> Block<'blk, 'tcx>)
1107-
-> Block<'blk, 'tcx> {
1109+
pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
1110+
val: ValueRef,
1111+
f: F)
1112+
-> Block<'blk, 'tcx> where
1113+
F: FnOnce(Block<'blk, 'tcx>) -> Block<'blk, 'tcx>,
1114+
{
11081115
let _icx = push_ctxt("with_cond");
11091116
let fcx = bcx.fcx;
11101117
let next_cx = fcx.new_temp_block("next");

src/librustc_trans/trans/cabi_x86_64.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -342,11 +342,13 @@ pub fn compute_abi_info(ccx: &CrateContext,
342342
atys: &[Type],
343343
rty: Type,
344344
ret_def: bool) -> FnType {
345-
fn x86_64_ty(ccx: &CrateContext,
346-
ty: Type,
347-
is_mem_cls: |cls: &[RegClass]| -> bool,
348-
ind_attr: Attribute)
349-
-> ArgType {
345+
fn x86_64_ty<F>(ccx: &CrateContext,
346+
ty: Type,
347+
is_mem_cls: F,
348+
ind_attr: Attribute)
349+
-> ArgType where
350+
F: FnOnce(&[RegClass]) -> bool,
351+
{
350352
if !ty.is_reg_ty() {
351353
let cls = classify_ty(ty);
352354
if is_mem_cls(cls.as_slice()) {

src/librustc_trans/trans/callee.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -781,15 +781,15 @@ pub fn trans_lang_call<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
781781
///
782782
/// For non-lang items, `dest` is always Some, and hence the result is written into memory
783783
/// somewhere. Nonetheless we return the actual return value of the function.
784-
pub fn trans_call_inner<'a, 'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
785-
call_info: Option<NodeInfo>,
786-
callee_ty: Ty<'tcx>,
787-
get_callee: |bcx: Block<'blk, 'tcx>,
788-
arg_cleanup_scope: cleanup::ScopeId|
789-
-> Callee<'blk, 'tcx>,
790-
args: CallArgs<'a, 'tcx>,
791-
dest: Option<expr::Dest>)
792-
-> Result<'blk, 'tcx> {
784+
pub fn trans_call_inner<'a, 'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
785+
call_info: Option<NodeInfo>,
786+
callee_ty: Ty<'tcx>,
787+
get_callee: F,
788+
args: CallArgs<'a, 'tcx>,
789+
dest: Option<expr::Dest>)
790+
-> Result<'blk, 'tcx> where
791+
F: FnOnce(Block<'blk, 'tcx>, cleanup::ScopeId) -> Callee<'blk, 'tcx>,
792+
{
793793
// Introduce a temporary cleanup scope that will contain cleanups
794794
// for the arguments while they are being evaluated. The purpose
795795
// this cleanup is to ensure that, should a panic occur while

src/librustc_trans/trans/cleanup.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -527,7 +527,7 @@ impl<'blk, 'tcx> CleanupHelperMethods<'blk, 'tcx> for FunctionContext<'blk, 'tcx
527527
self.scopes.borrow_mut().pop().unwrap()
528528
}
529529

530-
fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R {
530+
fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R {
531531
f(self.scopes.borrow().last().unwrap())
532532
}
533533

@@ -1145,5 +1145,5 @@ trait CleanupHelperMethods<'blk, 'tcx> {
11451145
fn scopes_len(&self) -> uint;
11461146
fn push_scope(&self, scope: CleanupScope<'blk, 'tcx>);
11471147
fn pop_scope(&self) -> CleanupScope<'blk, 'tcx>;
1148-
fn top_scope<R>(&self, f: |&CleanupScope<'blk, 'tcx>| -> R) -> R;
1148+
fn top_scope<R, F>(&self, f: F) -> R where F: FnOnce(&CleanupScope<'blk, 'tcx>) -> R;
11491149
}

src/librustc_trans/trans/datum.rs

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -113,15 +113,16 @@ pub fn immediate_rvalue_bcx<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
113113
/// it. The memory will be dropped upon exit from `scope`. The callback `populate` should
114114
/// initialize the memory. If `zero` is true, the space will be zeroed when it is allocated; this
115115
/// is not necessary unless `bcx` does not dominate the end of `scope`.
116-
pub fn lvalue_scratch_datum<'blk, 'tcx, A>(bcx: Block<'blk, 'tcx>,
117-
ty: Ty<'tcx>,
118-
name: &str,
119-
zero: bool,
120-
scope: cleanup::ScopeId,
121-
arg: A,
122-
populate: |A, Block<'blk, 'tcx>, ValueRef|
123-
-> Block<'blk, 'tcx>)
124-
-> DatumBlock<'blk, 'tcx, Lvalue> {
116+
pub fn lvalue_scratch_datum<'blk, 'tcx, A, F>(bcx: Block<'blk, 'tcx>,
117+
ty: Ty<'tcx>,
118+
name: &str,
119+
zero: bool,
120+
scope: cleanup::ScopeId,
121+
arg: A,
122+
populate: F)
123+
-> DatumBlock<'blk, 'tcx, Lvalue> where
124+
F: FnOnce(A, Block<'blk, 'tcx>, ValueRef) -> Block<'blk, 'tcx>,
125+
{
125126
let scratch = if zero {
126127
alloca_zeroed(bcx, ty, name)
127128
} else {
@@ -339,10 +340,10 @@ impl<'tcx> Datum<'tcx, Rvalue> {
339340
/// here since we can `match self.kind` rather than having to implement
340341
/// generic methods in `KindOps`.)
341342
impl<'tcx> Datum<'tcx, Expr> {
342-
fn match_kind<R>(self,
343-
if_lvalue: |Datum<'tcx, Lvalue>| -> R,
344-
if_rvalue: |Datum<'tcx, Rvalue>| -> R)
345-
-> R {
343+
fn match_kind<R, F, G>(self, if_lvalue: F, if_rvalue: G) -> R where
344+
F: FnOnce(Datum<'tcx, Lvalue>) -> R,
345+
G: FnOnce(Datum<'tcx, Rvalue>) -> R,
346+
{
346347
let Datum { val, ty, kind } = self;
347348
match kind {
348349
LvalueExpr => if_lvalue(Datum::new(val, ty, Lvalue)),
@@ -455,9 +456,11 @@ impl<'tcx> Datum<'tcx, Lvalue> {
455456
// datum may also be unsized _without the size information_. It is the
456457
// callers responsibility to package the result in some way to make a valid
457458
// datum in that case (e.g., by making a fat pointer or opened pair).
458-
pub fn get_element<'blk>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
459-
gep: |ValueRef| -> ValueRef)
460-
-> Datum<'tcx, Lvalue> {
459+
pub fn get_element<'blk, F>(&self, bcx: Block<'blk, 'tcx>, ty: Ty<'tcx>,
460+
gep: F)
461+
-> Datum<'tcx, Lvalue> where
462+
F: FnOnce(ValueRef) -> ValueRef,
463+
{
461464
let val = match self.ty.sty {
462465
_ if ty::type_is_sized(bcx.tcx(), self.ty) => gep(self.val),
463466
ty::ty_open(_) => {

src/librustc_trans/trans/debuginfo.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3212,13 +3212,13 @@ fn populate_scope_map(cx: &CrateContext,
32123212
});
32133213

32143214
// local helper functions for walking the AST.
3215-
fn with_new_scope(cx: &CrateContext,
3216-
scope_span: Span,
3217-
scope_stack: &mut Vec<ScopeStackEntry> ,
3218-
scope_map: &mut NodeMap<DIScope>,
3219-
inner_walk: |&CrateContext,
3220-
&mut Vec<ScopeStackEntry> ,
3221-
&mut NodeMap<DIScope>|) {
3215+
fn with_new_scope<F>(cx: &CrateContext,
3216+
scope_span: Span,
3217+
scope_stack: &mut Vec<ScopeStackEntry> ,
3218+
scope_map: &mut NodeMap<DIScope>,
3219+
inner_walk: F) where
3220+
F: FnOnce(&CrateContext, &mut Vec<ScopeStackEntry>, &mut NodeMap<DIScope>),
3221+
{
32223222
// Create a new lexical scope and push it onto the stack
32233223
let loc = cx.sess().codemap().lookup_char_pos(scope_span.lo);
32243224
let file_metadata = file_metadata(cx, loc.file.name.as_slice());

src/librustc_trans/trans/expr.rs

Lines changed: 51 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,7 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
295295
// into a type to be destructed. If we want to end up with a Box pointer,
296296
// then mk_ty should make a Box pointer (T -> Box<T>), if we want a
297297
// borrowed reference then it should be T -> &T.
298+
// FIXME(#19596) unbox `mk_ty`
298299
fn unsized_info<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
299300
kind: &ty::UnsizeKind<'tcx>,
300301
id: ast::NodeId,
@@ -341,27 +342,30 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
341342
debug!("dest_ty={}", unsized_ty.repr(bcx.tcx()));
342343
// Closures for extracting and manipulating the data and payload parts of
343344
// the fat pointer.
344-
let base = match k {
345-
&ty::UnsizeStruct(..) =>
346-
|bcx, val| PointerCast(bcx,
347-
val,
348-
type_of::type_of(bcx.ccx(), unsized_ty).ptr_to()),
349-
&ty::UnsizeLength(..) =>
350-
|bcx, val| GEPi(bcx, val, &[0u, 0u]),
351-
&ty::UnsizeVtable(..) =>
352-
|_bcx, val| PointerCast(bcx, val, Type::i8p(bcx.ccx()))
353-
};
354-
let info = |bcx, _val| unsized_info(bcx,
355-
k,
356-
expr.id,
357-
datum_ty,
358-
|t| ty::mk_rptr(tcx,
359-
ty::ReStatic,
360-
ty::mt{
361-
ty: t,
362-
mutbl: ast::MutImmutable
363-
}));
364-
into_fat_ptr(bcx, expr, datum, dest_ty, base, info)
345+
let info = |: bcx, _val| unsized_info(bcx,
346+
k,
347+
expr.id,
348+
datum_ty,
349+
|t| ty::mk_rptr(tcx,
350+
ty::ReStatic,
351+
ty::mt{
352+
ty: t,
353+
mutbl: ast::MutImmutable
354+
}));
355+
match *k {
356+
ty::UnsizeStruct(..) =>
357+
into_fat_ptr(bcx, expr, datum, dest_ty, |bcx, val| {
358+
PointerCast(bcx, val, type_of::type_of(bcx.ccx(), unsized_ty).ptr_to())
359+
}, info),
360+
ty::UnsizeLength(..) =>
361+
into_fat_ptr(bcx, expr, datum, dest_ty, |bcx, val| {
362+
GEPi(bcx, val, &[0u, 0u])
363+
}, info),
364+
ty::UnsizeVtable(..) =>
365+
into_fat_ptr(bcx, expr, datum, dest_ty, |_bcx, val| {
366+
PointerCast(bcx, val, Type::i8p(bcx.ccx()))
367+
}, info),
368+
}
365369
}
366370

367371
fn ref_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
@@ -370,18 +374,21 @@ fn apply_adjustments<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
370374
-> DatumBlock<'blk, 'tcx, Expr> {
371375
let tcx = bcx.tcx();
372376
let dest_ty = ty::close_type(tcx, datum.ty);
373-
let base = |bcx, val| Load(bcx, get_dataptr(bcx, val));
374-
let len = |bcx, val| Load(bcx, get_len(bcx, val));
377+
let base = |: bcx, val| Load(bcx, get_dataptr(bcx, val));
378+
let len = |: bcx, val| Load(bcx, get_len(bcx, val));
375379
into_fat_ptr(bcx, expr, datum, dest_ty, base, len)
376380
}
377381

378-
fn into_fat_ptr<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
379-
expr: &ast::Expr,
380-
datum: Datum<'tcx, Expr>,
381-
dest_ty: Ty<'tcx>,
382-
base: |Block<'blk, 'tcx>, ValueRef| -> ValueRef,
383-
info: |Block<'blk, 'tcx>, ValueRef| -> ValueRef)
384-
-> DatumBlock<'blk, 'tcx, Expr> {
382+
fn into_fat_ptr<'blk, 'tcx, F, G>(bcx: Block<'blk, 'tcx>,
383+
expr: &ast::Expr,
384+
datum: Datum<'tcx, Expr>,
385+
dest_ty: Ty<'tcx>,
386+
base: F,
387+
info: G)
388+
-> DatumBlock<'blk, 'tcx, Expr> where
389+
F: FnOnce(Block<'blk, 'tcx>, ValueRef) -> ValueRef,
390+
G: FnOnce(Block<'blk, 'tcx>, ValueRef) -> ValueRef,
391+
{
385392
let mut bcx = bcx;
386393

387394
// Arrange cleanup
@@ -659,17 +666,19 @@ fn trans_datum_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
659666
}
660667
}
661668

662-
fn trans_field<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
663-
base: &ast::Expr,
664-
get_idx: |&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]| -> uint)
665-
-> DatumBlock<'blk, 'tcx, Expr> {
669+
fn trans_field<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>,
670+
base: &ast::Expr,
671+
get_idx: F)
672+
-> DatumBlock<'blk, 'tcx, Expr> where
673+
F: FnOnce(&'blk ty::ctxt<'tcx>, &[ty::field<'tcx>]) -> uint,
674+
{
666675
let mut bcx = bcx;
667676
let _icx = push_ctxt("trans_rec_field");
668677

669678
let base_datum = unpack_datum!(bcx, trans_to_lvalue(bcx, base, "field"));
670679
let bare_ty = ty::unopen_type(base_datum.ty);
671680
let repr = adt::represent_type(bcx.ccx(), bare_ty);
672-
with_field_tys(bcx.tcx(), bare_ty, None, |discr, field_tys| {
681+
with_field_tys(bcx.tcx(), bare_ty, None, move |discr, field_tys| {
673682
let ix = get_idx(bcx.tcx(), field_tys);
674683
let d = base_datum.get_element(
675684
bcx,
@@ -1254,11 +1263,13 @@ pub fn trans_local_var<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
12541263
/// Helper for enumerating the field types of structs, enums, or records. The optional node ID here
12551264
/// is the node ID of the path identifying the enum variant in use. If none, this cannot possibly
12561265
/// an enum variant (so, if it is and `node_id_opt` is none, this function panics).
1257-
pub fn with_field_tys<'tcx, R>(tcx: &ty::ctxt<'tcx>,
1258-
ty: Ty<'tcx>,
1259-
node_id_opt: Option<ast::NodeId>,
1260-
op: |ty::Disr, (&[ty::field<'tcx>])| -> R)
1261-
-> R {
1266+
pub fn with_field_tys<'tcx, R, F>(tcx: &ty::ctxt<'tcx>,
1267+
ty: Ty<'tcx>,
1268+
node_id_opt: Option<ast::NodeId>,
1269+
op: F)
1270+
-> R where
1271+
F: FnOnce(ty::Disr, &[ty::field<'tcx>]) -> R,
1272+
{
12621273
match ty.sty {
12631274
ty::ty_struct(did, ref substs) => {
12641275
op(0, struct_fields(tcx, did, substs).as_slice())

0 commit comments

Comments
 (0)