librustc: Tie up loose ends in unboxed closures.

This patch primarily does two things: (1) it prevents lifetimes from
leaking out of unboxed closures; (2) it allows unboxed closure type
notation, call notation, and construction notation to construct closures
matching any of the three traits.

This breaks code that looked like:

    let mut f;
    {
        let x = &5i;
        f = |&mut:| *x + 10;
    }

Change this code to avoid having a reference escape. For example:

    {
        let x = &5i;
        let mut f; // <-- move here to avoid dangling reference
        f = |&mut:| *x + 10;
    }

I believe this is enough to consider unboxed closures essentially
implemented. Further issues (for example, higher-rank lifetimes) should
be filed as followups.

Closes #14449.

[breaking-change]
This commit is contained in:
Patrick Walton
2014-07-29 22:08:39 -07:00
parent 9d45d63d0d
commit 8d27232141
43 changed files with 834 additions and 297 deletions

View File

@@ -368,6 +368,7 @@ pub fn noop_fold_ty<T: Folder>(t: P<Ty>, fld: &mut T) -> P<Ty> {
TyUnboxedFn(ref f) => {
TyUnboxedFn(box(GC) UnboxedFnTy {
decl: fld.fold_fn_decl(&*f.decl),
kind: f.kind,
})
}
TyTup(ref tys) => TyTup(tys.iter().map(|&ty| fld.fold_ty(ty)).collect()),
@@ -641,6 +642,7 @@ pub fn noop_fold_ty_param_bound<T: Folder>(tpb: &TyParamBound, fld: &mut T)
UnboxedFnTyParamBound(ref unboxed_function_type) => {
UnboxedFnTyParamBound(UnboxedFnTy {
decl: fld.fold_fn_decl(&*unboxed_function_type.decl),
kind: unboxed_function_type.kind,
})
}
OtherRegionTyParamBound(s) => OtherRegionTyParamBound(s)
@@ -1103,8 +1105,9 @@ pub fn noop_fold_expr<T: Folder>(e: Gc<Expr>, folder: &mut T) -> Gc<Expr> {
ExprProc(folder.fold_fn_decl(&**decl),
folder.fold_block(body.clone()))
}
ExprUnboxedFn(capture_clause, ref decl, ref body) => {
ExprUnboxedFn(capture_clause, kind, ref decl, ref body) => {
ExprUnboxedFn(capture_clause,
kind,
folder.fold_fn_decl(&**decl),
folder.fold_block(*body))
}