11# Closure types
22
3+ r[ type.closure]
4+
35A [ closure expression] produces a closure value with a unique, anonymous type
46that cannot be written out. A closure type is approximately equivalent to a
57struct which contains the captured variables. For instance, the following
@@ -47,21 +49,27 @@ f(Closure{s: s, t: &t});
4749
4850## Capture modes
4951
52+ r[ type.closure.capture]
53+
54+ r[ type.closure.capture.order]
5055The compiler prefers to capture a closed-over variable by immutable borrow,
5156followed by unique immutable borrow (see below), by mutable borrow, and finally
5257by move. It will pick the first choice of these that is compatible with how the
5358captured variable is used inside the closure body. The compiler does not take
5459surrounding code into account, such as the lifetimes of involved variables, or
5560of the closure itself.
5661
62+ r[ type.closure.capture.move]
5763If the ` move ` keyword is used, then all captures are by move or, for ` Copy `
5864types, by copy, regardless of whether a borrow would work. The ` move ` keyword is
5965usually used to allow the closure to outlive the captured values, such as if the
6066closure is being returned or used to spawn a new thread.
6167
68+ r[ type.closure.capture.composite]
6269Composite types such as structs, tuples, and enums are always captured entirely,
6370not by individual fields. It may be necessary to borrow into a local variable in
6471order to capture a single field:
72+ <!-- editor note, not true in Edition 2021 -->
6573
6674``` rust
6775# use std :: collections :: HashSet ;
@@ -87,6 +95,8 @@ borrowed to iterate over, the code would not compile.
8795
8896## Unique immutable borrows in captures
8997
98+ r[ type.closure.unique-immutable]
99+
90100Captures can occur by a special kind of borrow called a _ unique immutable
91101borrow_ , which cannot be used anywhere else in the language and cannot be
92102written out explicitly. It occurs when modifying the referent of a mutable
@@ -115,13 +125,18 @@ the closure's lifetime has expired at the end of the block, releasing the borrow
115125
116126## Call traits and coercions
117127
128+ r[ type.closure.call]
129+
130+ r[ type.closure.call.intro]
118131Closure types all implement [ ` FnOnce ` ] , indicating that they can be called once
119132by consuming ownership of the closure. Additionally, some closures implement
120133more specific call traits:
121134
135+ r[ type.closure.call.fn-mut]
122136* A closure which does not move out of any captured variables implements
123137 [ ` FnMut ` ] , indicating that it can be called by mutable reference.
124138
139+ r[ type.closure.call.fn]
125140* A closure which does not mutate or move out of any captured variables
126141 implements [ ` Fn ` ] , indicating that it can be called by shared reference.
127142
@@ -130,6 +145,7 @@ more specific call traits:
130145> closure type are determined by what the closure does with captured values,
131146> not how it captures them.
132147
148+ r[ type.closure.non-capturing]
133149* Non-capturing closures* are closures that don't capture anything from their
134150environment. They can be coerced to function pointers (e.g., ` fn() ` )
135151with the matching signature.
@@ -146,6 +162,9 @@ x = bo(5,7);
146162
147163## Other traits
148164
165+ r[ type.closure.traits]
166+
167+ r[ type.closure.traits.intro]
149168All closure types implement [ ` Sized ` ] . Additionally, closure types implement the
150169following traits if allowed to do so by the types of the captures it stores:
151170
@@ -154,6 +173,7 @@ following traits if allowed to do so by the types of the captures it stores:
154173* [ ` Sync ` ]
155174* [ ` Send ` ]
156175
176+ r[ type.closure.traits.behavior]
157177The rules for [ ` Send ` ] and [ ` Sync ` ] match those for normal struct types, while
158178[ ` Clone ` ] and [ ` Copy ` ] behave as if [ derived] . For [ ` Clone ` ] , the order of
159179cloning of the captured variables is left unspecified.
0 commit comments