1
Fork 0

rustc: unbox closures used in function arguments

This commit is contained in:
Jorge Aparicio 2014-12-30 19:59:09 -05:00
parent 70ce68eed4
commit 5de9f47e49
2 changed files with 59 additions and 53 deletions

View file

@ -1122,11 +1122,15 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
}) })
} }
// FIXME(#19596) unbox `op` pub fn cat_pattern<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, mut op: F) where
pub fn cat_pattern(&self, F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat),
cmt: cmt<'tcx>, {
pat: &ast::Pat, self.cat_pattern_(cmt, pat, &mut op)
op: |&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat|) }
// FIXME(#19596) This is a workaround, but there should be a better way to do this
fn cat_pattern_<F>(&self, cmt: cmt<'tcx>, pat: &ast::Pat, op: &mut F) where
F: FnMut(&MemCategorizationContext<'t, TYPER>, cmt<'tcx>, &ast::Pat),
{ {
// Here, `cmt` is the categorization for the value being // Here, `cmt` is the categorization for the value being
// matched and pat is the pattern it is being matched against. // matched and pat is the pattern it is being matched against.
@ -1177,7 +1181,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
pat.id, pprust::pat_to_string(pat), pat.id, pprust::pat_to_string(pat),
cmt.repr(self.tcx())); cmt.repr(self.tcx()));
op(self, cmt.clone(), pat); (*op)(self, cmt.clone(), pat);
let def_map = self.tcx().def_map.borrow(); let def_map = self.tcx().def_map.borrow();
let opt_def = def_map.get(&pat.id); let opt_def = def_map.get(&pat.id);
@ -1214,7 +1218,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
pat, cmt.clone(), subpat_ty, pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i))); InteriorField(PositionalField(i)));
self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z)); self.cat_pattern_(subcmt, &**subpat, op);
} }
} }
Some(&def::DefStruct(..)) => { Some(&def::DefStruct(..)) => {
@ -1224,13 +1228,12 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
self.cat_imm_interior( self.cat_imm_interior(
pat, cmt.clone(), subpat_ty, pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i))); InteriorField(PositionalField(i)));
self.cat_pattern(cmt_field, &**subpat, self.cat_pattern_(cmt_field, &**subpat, op);
|x,y,z| op(x,y,z));
} }
} }
Some(&def::DefConst(..)) => { Some(&def::DefConst(..)) => {
for subpat in subpats.iter() { for subpat in subpats.iter() {
self.cat_pattern(cmt.clone(), &**subpat, |x,y,z| op(x,y,z)); self.cat_pattern_(cmt.clone(), &**subpat, op);
} }
} }
_ => { _ => {
@ -1242,7 +1245,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
} }
ast::PatIdent(_, _, Some(ref subpat)) => { ast::PatIdent(_, _, Some(ref subpat)) => {
self.cat_pattern(cmt, &**subpat, op); self.cat_pattern_(cmt, &**subpat, op);
} }
ast::PatIdent(_, _, None) => { ast::PatIdent(_, _, None) => {
@ -1254,7 +1257,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
for fp in field_pats.iter() { for fp in field_pats.iter() {
let field_ty = self.pat_ty(&*fp.node.pat); // see (*2) let field_ty = self.pat_ty(&*fp.node.pat); // see (*2)
let cmt_field = self.cat_field(pat, cmt.clone(), fp.node.ident.name, field_ty); let cmt_field = self.cat_field(pat, cmt.clone(), fp.node.ident.name, field_ty);
self.cat_pattern(cmt_field, &*fp.node.pat, |x,y,z| op(x,y,z)); self.cat_pattern_(cmt_field, &*fp.node.pat, op);
} }
} }
@ -1266,29 +1269,28 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> {
self.cat_imm_interior( self.cat_imm_interior(
pat, cmt.clone(), subpat_ty, pat, cmt.clone(), subpat_ty,
InteriorField(PositionalField(i))); InteriorField(PositionalField(i)));
self.cat_pattern(subcmt, &**subpat, |x,y,z| op(x,y,z)); self.cat_pattern_(subcmt, &**subpat, op);
} }
} }
ast::PatBox(ref subpat) | ast::PatRegion(ref subpat) => { ast::PatBox(ref subpat) | ast::PatRegion(ref subpat) => {
// @p1, ~p1, ref p1 // @p1, ~p1, ref p1
let subcmt = self.cat_deref(pat, cmt, 0, false); let subcmt = self.cat_deref(pat, cmt, 0, false);
self.cat_pattern(subcmt, &**subpat, op); self.cat_pattern_(subcmt, &**subpat, op);
} }
ast::PatVec(ref before, ref slice, ref after) => { ast::PatVec(ref before, ref slice, ref after) => {
let elt_cmt = self.cat_index(pat, self.deref_vec(pat, cmt)); let elt_cmt = self.cat_index(pat, self.deref_vec(pat, cmt));
for before_pat in before.iter() { for before_pat in before.iter() {
self.cat_pattern(elt_cmt.clone(), &**before_pat, self.cat_pattern_(elt_cmt.clone(), &**before_pat, op);
|x,y,z| op(x,y,z));
} }
for slice_pat in slice.iter() { for slice_pat in slice.iter() {
let slice_ty = self.pat_ty(&**slice_pat); let slice_ty = self.pat_ty(&**slice_pat);
let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty); let slice_cmt = self.cat_rvalue_node(pat.id(), pat.span(), slice_ty);
self.cat_pattern(slice_cmt, &**slice_pat, |x,y,z| op(x,y,z)); self.cat_pattern_(slice_cmt, &**slice_pat, op);
} }
for after_pat in after.iter() { for after_pat in after.iter() {
self.cat_pattern(elt_cmt.clone(), &**after_pat, |x,y,z| op(x,y,z)); self.cat_pattern_(elt_cmt.clone(), &**after_pat, op);
} }
} }

View file

@ -2812,49 +2812,53 @@ pub fn walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where
maybe_walk_ty(ty, |ty| { f(ty); true }); maybe_walk_ty(ty, |ty| { f(ty); true });
} }
// FIXME(#19596) unbox `f` pub fn maybe_walk_ty<'tcx, F>(ty: Ty<'tcx>, mut f: F) where F: FnMut(Ty<'tcx>) -> bool {
pub fn maybe_walk_ty<'tcx>(ty: Ty<'tcx>, f: |Ty<'tcx>| -> bool) { // FIXME(#19596) This is a workaround, but there should be a better way to do this
if !f(ty) { fn maybe_walk_ty_<'tcx, F>(ty: Ty<'tcx>, f: &mut F) where F: FnMut(Ty<'tcx>) -> bool {
return; if !(*f)(ty) {
} return;
match ty.sty {
ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
ty_str | ty_infer(_) | ty_param(_) | ty_err => {}
ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty(ty, f),
ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
maybe_walk_ty(tm.ty, f);
} }
ty_trait(box TyTrait { ref principal, .. }) => { match ty.sty {
for subty in principal.0.substs.types.iter() { ty_bool | ty_char | ty_int(_) | ty_uint(_) | ty_float(_) |
maybe_walk_ty(*subty, |x| f(x)); ty_str | ty_infer(_) | ty_param(_) | ty_err => {}
ty_uniq(ty) | ty_vec(ty, _) | ty_open(ty) => maybe_walk_ty_(ty, f),
ty_ptr(ref tm) | ty_rptr(_, ref tm) => {
maybe_walk_ty_(tm.ty, f);
} }
} ty_trait(box TyTrait { ref principal, .. }) => {
ty_projection(ProjectionTy { ref trait_ref, .. }) => { for subty in principal.0.substs.types.iter() {
for subty in trait_ref.substs.types.iter() { maybe_walk_ty_(*subty, f);
maybe_walk_ty(*subty, |x| f(x)); }
} }
} ty_projection(ProjectionTy { ref trait_ref, .. }) => {
ty_enum(_, ref substs) | for subty in trait_ref.substs.types.iter() {
ty_struct(_, ref substs) | maybe_walk_ty_(*subty, f);
ty_unboxed_closure(_, _, ref substs) => { }
for subty in substs.types.iter() {
maybe_walk_ty(*subty, |x| f(x));
} }
} ty_enum(_, ref substs) |
ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty(*tt, |x| f(x)); } } ty_struct(_, ref substs) |
ty_bare_fn(_, ref ft) => { ty_unboxed_closure(_, _, ref substs) => {
for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); } for subty in substs.types.iter() {
if let ty::FnConverging(output) = ft.sig.0.output { maybe_walk_ty_(*subty, f);
maybe_walk_ty(output, f); }
} }
} ty_tup(ref ts) => { for tt in ts.iter() { maybe_walk_ty_(*tt, f); } }
ty_closure(ref ft) => { ty_bare_fn(_, ref ft) => {
for a in ft.sig.0.inputs.iter() { maybe_walk_ty(*a, |x| f(x)); } for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); }
if let ty::FnConverging(output) = ft.sig.0.output { if let ty::FnConverging(output) = ft.sig.0.output {
maybe_walk_ty(output, f); maybe_walk_ty_(output, f);
}
}
ty_closure(ref ft) => {
for a in ft.sig.0.inputs.iter() { maybe_walk_ty_(*a, f); }
if let ty::FnConverging(output) = ft.sig.0.output {
maybe_walk_ty_(output, f);
}
} }
} }
} }
maybe_walk_ty_(ty, &mut f);
} }
// Folds types from the bottom up. // Folds types from the bottom up.