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:
@@ -528,7 +528,7 @@ pub enum Expr_ {
|
||||
ExprMatch(Gc<Expr>, Vec<Arm>),
|
||||
ExprFnBlock(CaptureClause, P<FnDecl>, P<Block>),
|
||||
ExprProc(P<FnDecl>, P<Block>),
|
||||
ExprUnboxedFn(CaptureClause, P<FnDecl>, P<Block>),
|
||||
ExprUnboxedFn(CaptureClause, UnboxedClosureKind, P<FnDecl>, P<Block>),
|
||||
ExprBlock(P<Block>),
|
||||
|
||||
ExprAssign(Gc<Expr>, Gc<Expr>),
|
||||
@@ -900,6 +900,7 @@ pub struct BareFnTy {
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||
pub struct UnboxedFnTy {
|
||||
pub kind: UnboxedClosureKind,
|
||||
pub decl: P<FnDecl>,
|
||||
}
|
||||
|
||||
@@ -1297,6 +1298,13 @@ pub enum ForeignItem_ {
|
||||
ForeignItemStatic(P<Ty>, /* is_mutbl */ bool),
|
||||
}
|
||||
|
||||
#[deriving(Clone, PartialEq, Eq, Encodable, Decodable, Hash, Show)]
|
||||
pub enum UnboxedClosureKind {
|
||||
FnUnboxedClosureKind,
|
||||
FnMutUnboxedClosureKind,
|
||||
FnOnceUnboxedClosureKind,
|
||||
}
|
||||
|
||||
/// The data we save and restore about an inlined item or method. This is not
|
||||
/// part of the AST that we parse from a file, but it becomes part of the tree
|
||||
/// that we trans.
|
||||
|
||||
Reference in New Issue
Block a user