r[type.closure]
# Closure types

r[type.closure.intro]
A [closure expression] produces a closure value with a unique, anonymous type that cannot be written out.
A closure type is approximately equivalent to a struct which contains the captured values.
For instance, the following closure:

```rust
#[derive(Debug)]
struct Point { x: i32, y: i32 }
struct Rectangle { left_top: Point, right_bottom: Point }

fn f<F : FnOnce() -> String> (g: F) {
    println!("{}", g());
}

let mut rect = Rectangle {
    left_top: Point { x: 1, y: 1 },
    right_bottom: Point { x: 0, y: 0 }
};

let c = || {
    rect.left_top.x += 1;
    rect.right_bottom.x += 1;
    format!("{:?}", rect.left_top)
};
f(c); // Prints "Point { x: 2, y: 1 }".
```

generates a closure type roughly like the following:

<!-- ignore: simplified -->
```rust,ignore
// Note: This is not exactly how it is translated, this is only for
// illustration.

struct Closure<'a> {
    left_top : &'a mut Point,
    right_bottom_x : &'a mut i32,
}

impl<'a> FnOnce<()> for Closure<'a> {
    type Output = String;
    extern "rust-call" fn call_once(self, args: ()) -> String {
        self.left_top.x += 1;
        *self.right_bottom_x += 1;
        format!("{:?}", self.left_top)
    }
}
```

so that the call to `f` works as if it were:

<!-- ignore: continuation of above -->
```rust,ignore
f(Closure{ left_top: &mut rect.left_top, right_bottom_x: &mut rect.right_bottom.x });
```

r[type.closure.capture]
## Capture modes

r[type.closure.capture.intro]
A *capture mode* determines how a [place expression] from the environment is borrowed or moved into the closure.
The capture modes are:

1. Immutable borrow (`ImmBorrow`) --- The place expression is captured as a [shared reference].
2. Unique immutable borrow (`UniqueImmBorrow`) --- This is similar to an immutable borrow, but must be unique as described [below](#unique-immutable-borrows-in-captures).
3. Mutable borrow (`MutBorrow`) --- The place expression is captured as a [mutable reference].
4. Move (`ByValue`) --- The place expression is captured by [moving the value] into the closure.

r[type.closure.capture.precedence]
Place expressions from the environment are captured from the first mode that is compatible with how the captured value is used inside the closure body.
The mode is not affected by the code surrounding the closure, such as the lifetimes of involved variables or fields, or of the closure itself.

[moving the value]: ../expressions.md#moved-and-copied-types
[mutable reference]: pointer.md#mutable-references-mut
[place expression]: ../expressions.md#place-expressions-and-value-expressions
[shared reference]: pointer.md#references--and-mut

r[type.closure.capture.copy]
### `Copy` values

Values that implement [`Copy`] that are moved into the closure are captured with the `ImmBorrow` mode.

```rust
let x = [0; 1024];
let c = || {
    let y = x; // x captured by ImmBorrow
};
```

r[type.closure.async.input]
### Async input capture

Async closures always capture all input arguments, regardless of whether or not they are used within the body.

## Capture precision

r[type.closure.capture.precision.capture-path]
A *capture path* is a sequence starting with a variable from the environment followed by zero or more place projections from that variable.

r[type.closure.capture.precision.place-projection]
A *place projection* is a [field access], [tuple index], [dereference] (and automatic dereferences), [array or slice index] expression, or [pattern destructuring] applied to a variable.

> [!NOTE]
> In `rustc`, pattern destructuring desugars into a series of dereferences and field or element accesses.

r[type.closure.capture.precision.intro]
The closure borrows or moves the capture path, which may be truncated based on the rules described below.

For example:

```rust
struct SomeStruct {
    f1: (i32, i32),
}
let s = SomeStruct { f1: (1, 2) };

let c = || {
    let x = s.f1.1; // s.f1.1 captured by ImmBorrow
};
c();
```

Here the capture path is the local variable `s`, followed by a field access `.f1`, and then a tuple index `.1`.
This closure captures an immutable borrow of `s.f1.1`.

[field access]: ../expressions/field-expr.md
[pattern destructuring]: patterns.destructure
[tuple index]: ../expressions/tuple-expr.md#tuple-indexing-expressions
[dereference]: ../expressions/operator-expr.md#the-dereference-operator
[array or slice index]: ../expressions/array-expr.md#array-and-slice-indexing-expressions

r[type.closure.capture.precision.shared-prefix]
### Shared prefix

In the case where a capture path and one of the ancestors of that path are both captured by a closure, the ancestor path is captured with the highest capture mode among the two captures, `CaptureMode = max(AncestorCaptureMode, DescendantCaptureMode)`, using the strict weak ordering:

`ImmBorrow < UniqueImmBorrow < MutBorrow < ByValue`

Note that this might need to be applied recursively.

```rust
// In this example, there are three different capture paths with a shared ancestor:
# fn move_value<T>(_: T){}
let s = String::from("S");
let t = (s, String::from("T"));
let mut u = (t, String::from("U"));

let c = || {
    println!("{:?}", u); // u captured by ImmBorrow
    u.1.truncate(0); // u.0 captured by MutBorrow
    move_value(u.0.0); // u.0.0 captured by ByValue
};
c();
```

Overall this closure will capture `u` by `ByValue`.

r[type.closure.capture.precision.dereference-shared]
### Rightmost shared reference truncation

The capture path is truncated at the rightmost dereference in the capture path if the dereference is applied to a shared reference.

This truncation is allowed because fields that are read through a shared reference will always be read via a shared reference or a copy.
This helps reduce the size of the capture when the extra precision does not yield any benefit from a borrow checking perspective.

The reason it is the *rightmost* dereference is to help avoid a shorter lifetime than is necessary.
Consider the following example:

```rust
struct Int(i32);
struct B<'a>(&'a i32);

struct MyStruct<'a> {
   a: &'static Int,
   b: B<'a>,
}

fn foo<'a, 'b>(m: &'a MyStruct<'b>) -> impl FnMut() + 'static {
    let c = || drop(&m.a.0);
    c
}
```

If this were to capture `m`, then the closure would no longer outlive `'static`, since `m` is constrained to `'a`. Instead, it captures `(*(*m).a)` by `ImmBorrow`.

r[type.closure.capture.precision.wildcard]
### Wildcard pattern bindings

r[type.closure.capture.precision.wildcard.reads]
Closures only capture data that needs to be read. Binding a value with a [wildcard pattern] does not read the value, so the place is not captured.

```rust,no_run
struct S; // A non-`Copy` type.
let x = S;
let c = || {
    let _ = x;  // Does not capture `x`.
};
let c = || match x {
    _ => (), // Does not capture `x`.
};
x; // OK: `x` can be moved here.
c();
```

r[type.closure.capture.precision.wildcard.destructuring]
Destructuring tuples, structs, and single-variant enums does not, by itself, cause a read or the place to be captured.

> [!NOTE]
> Enums marked with [`#[non_exhaustive]`][attributes.type-system.non_exhaustive] from other crates are always treated as having multiple variants. See *[type.closure.capture.precision.discriminants.non_exhaustive]*.

```rust,no_run
struct S; // A non-`Copy` type.

// Destructuring tuples does not cause a read or capture.
let x = (S,);
let c = || {
    let (..) = x; // Does not capture `x`.
};
x; // OK: `x` can be moved here.
c();

// Destructuring unit structs does not cause a read or capture.
let x = S;
let c = || {
    let S = x; // Does not capture `x`.
};
x; // OK: `x` can be moved here.
c();

// Destructuring structs does not cause a read or capture.
struct W<T>(T);
let x = W(S);
let c = || {
    let W(..) = x; // Does not capture `x`.
};
x; // OK: `x` can be moved here.
c();

// Destructuring single-variant enums does not cause a read
// or capture.
enum E<T> { V(T) }
let x = E::V(S);
let c = || {
    let E::V(..) = x; // Does not capture `x`.
};
x; // OK: `x` can be moved here.
c();
```

r[type.closure.capture.precision.wildcard.fields]
Fields matched against [RestPattern] (`..`) or [StructPatternEtCetera] (also `..`) are not read, and those fields are not captured.

```rust,no_run
struct S; // A non-`Copy` type.
let x = (S, S);
let c = || {
    let (x0, ..) = x;  // Captures `x.0` by `ByValue`.
};
// Only the first tuple field was captured by the closure.
x.1; // OK: `x.1` can be moved here.
c();
```

r[type.closure.capture.precision.wildcard.array-slice]
Partial captures of arrays and slices are not supported; the entire slice or array is always captured even if used with wildcard pattern matching, indexing, or sub-slicing.

```rust,compile_fail,E0382
struct S; // A non-`Copy` type.
let mut x = [S, S];
let c = || {
    let [x0, _] = x; // Captures all of `x` by `ByValue`.
};
let _ = &mut x[1]; // ERROR: Borrow of moved value.
```

r[type.closure.capture.precision.wildcard.initialized]
Values that are matched with wildcards must still be initialized.

```rust,compile_fail,E0381
let x: u8;
let c = || {
    let _ = x; // ERROR: Binding `x` isn't initialized.
};
```

[wildcard pattern]: ../patterns.md#wildcard-pattern

r[type.closure.capture.precision.discriminants]
### Capturing for discriminant reads

r[type.closure.capture.precision.discriminants.reads]
If pattern matching reads a discriminant, the place containing that discriminant is captured by `ImmBorrow`.

r[type.closure.capture.precision.discriminants.multiple-variant]
Matching against a variant of an enum that has more than one variant reads the discriminant, capturing the place by `ImmBorrow`.

```rust,compile_fail,E0502
struct S; // A non-`Copy` type.
let mut x = (Some(S), S);
let c = || match x {
    (None, _) => (),
//   ^^^^
// This pattern requires reading the discriminant, which
// causes `x.0` to be captured by `ImmBorrow`.
    _ => (),
};
let _ = &mut x.0; // ERROR: Cannot borrow `x.0` as mutable.
//           ^^^
// The closure is still live, so `x.0` is still immutably
// borrowed here.
c();
```

```rust,no_run
# struct S; // A non-`Copy` type.
# let x = (Some(S), S);
let c = || match x { // Captures `x.0` by `ImmBorrow`.
    (None, _) => (),
    _ => (),
};
// Though `x.0` is captured due to the discriminant read,
// `x.1` is not captured.
x.1; // OK: `x.1` can be moved here.
c();
```

r[type.closure.capture.precision.discriminants.single-variant]
Matching against the only variant of a single-variant enum does not read the discriminant and does not capture the place.

```rust,no_run
enum E<T> { V(T) } // A single-variant enum.
let x = E::V(());
let c = || {
    let E::V(_) = x; // Does not capture `x`.
};
x; // OK: `x` can be moved here.
c();
```

r[type.closure.capture.precision.discriminants.non_exhaustive]
If [`#[non_exhaustive]`][attributes.type-system.non_exhaustive] is applied to an enum defined in an external crate, the enum is treated as having multiple variants for the purpose of deciding whether a read occurs, even if it actually has only one variant.

r[type.closure.capture.precision.discriminants.uninhabited-variants]
Even if all variants but the one being matched against are uninhabited, making the pattern [irrefutable][patterns.refutable], the discriminant is still read if it otherwise would be.

```rust,compile_fail,E0502
enum Empty {}
let mut x = Ok::<_, Empty>(42);
let c = || {
    let Ok(_) = x; // Captures `x` by `ImmBorrow`.
};
let _ = &mut x; // ERROR: Cannot borrow `x` as mutable.
c();
```


r[type.closure.capture.precision.range-patterns]
### Capturing and range patterns

r[type.closure.capture.precision.range-patterns.reads]
Matching against a [range pattern][patterns.range] reads the place being matched, even if the range includes all possible values of the type, and captures the place by `ImmBorrow`.

```rust,compile_fail,E0502
let mut x = 0u8;
let c = || {
    let 0..=u8::MAX = x; // Captures `x` by `ImmBorrow`.
};
let _ = &mut x; // ERROR: Cannot borrow `x` as mutable.
c();
```

r[type.closure.capture.precision.slice-patterns]
### Capturing and slice patterns

r[type.closure.capture.precision.slice-patterns.slices]
Matching a slice against a [slice pattern][patterns.slice] other than one with only a single [rest pattern][patterns.rest] (i.e. `[..]`) is treated as a read of the length from the slice and captures the slice by `ImmBorrow`.

```rust,compile_fail,E0502
let x: &mut [u8] = &mut [];
let c = || match x { // Captures `*x` by `ImmBorrow`.
    &mut [] => (),
//       ^^
// This matches a slice of exactly zero elements. To know whether the
// scrutinee matches, the length must be read, causing the slice to
// be captured.
    _ => (),
};
let _ = &mut *x; // ERROR: Cannot borrow `*x` as mutable.
c();
```

```rust,no_run
let x: &mut [u8] = &mut [];
let c = || match x { // Does not capture `*x`.
    [..] => (),
//   ^^ Rest pattern.
};
let _ = &mut *x; // OK: `*x` can be borrow here.
c();
```

> [!NOTE]
> Perhaps surprisingly, even though the length is contained in the (wide) *pointer* to the slice, it is the place of the *pointee* (the slice) that is treated as read and is captured.
>
> ```rust,no_run
> fn f<'l: 's, 's>(x: &'s mut &'l [u8]) -> impl Fn() + 'l {
>     // The closure outlives `'l` because it captures `**x`. If
>     // instead it captured `*x`, it would not live long enough
>     // to satisfy the `impl Fn() + 'l` bound.
>     || match *x { // Captures `**x` by `ImmBorrow`.
>         &[] => (),
>         _ => (),
>     }
> }
> ```
>
> In this way, the behavior is consistent with dereferencing to the slice in the scrutinee.
>
> ```rust,no_run
> fn f<'l: 's, 's>(x: &'s mut &'l [u8]) -> impl Fn() + 'l {
>     || match **x { // Captures `**x` by `ImmBorrow`.
>         [] => (),
>         _ => (),
>     }
> }
> ```
>
> For details, see [Rust PR #138961](https://github.com/rust-lang/rust/pull/138961).

r[type.closure.capture.precision.slice-patterns.arrays]
As the length of an array is fixed by its type, matching an array against a slice pattern does not by itself capture the place.

```rust,no_run
let x: [u8; 1] = [0];
let c = || match x { // Does not capture `x`.
    [_] => (), // Length is fixed.
};
x; // OK: `x` can be moved here.
c();
```

r[type.closure.capture.precision.move-dereference]
### Capturing references in move contexts

Because it is not allowed to move fields out of a reference, `move` closures will only capture the prefix of a capture path that runs up to, but not including, the first dereference of a reference.
The reference itself will be moved into the closure.

```rust
struct T(String, String);

let mut t = T(String::from("foo"), String::from("bar"));
let t_mut_ref = &mut t;
let mut c = move || {
    t_mut_ref.0.push_str("123"); // captures `t_mut_ref` ByValue
};
c();
```

r[type.closure.capture.precision.raw-pointer-dereference]
### Raw pointer dereference

Because it is `unsafe` to dereference a raw pointer, closures will only capture the prefix of a capture path that runs up to, but not including, the first dereference of a raw pointer.

```rust
struct T(String, String);

let t = T(String::from("foo"), String::from("bar"));
let t_ptr = &t as *const T;

let c = || unsafe {
    println!("{}", (*t_ptr).0); // captures `t_ptr` by ImmBorrow
};
c();
```

r[type.closure.capture.precision.union]
### Union fields

Because it is `unsafe` to access a union field, closures will only capture the prefix of a capture path that runs up to the union itself.

```rust
union U {
    a: (i32, i32),
    b: bool,
}
let u = U { a: (123, 456) };

let c = || {
    let x = unsafe { u.a.0 }; // captures `u` ByValue
};
c();

// This also includes writing to fields.
let mut u = U { a: (123, 456) };

let mut c = || {
    u.b = true; // captures `u` with MutBorrow
};
c();
```

r[type.closure.capture.precision.unaligned]
### Reference into unaligned `struct`s

Because it is [undefined behavior] to create references to unaligned fields in a structure,
closures will only capture the prefix of the capture path that runs up to, but not including, the first field access into a structure that uses [the `packed` representation].
This includes all fields, even those that are aligned, to protect against compatibility concerns should any of the fields in the structure change in the future.

```rust
#[repr(packed)]
struct T(i32, i32);

let t = T(2, 5);
let c = || {
    let a = t.0; // captures `t` with ImmBorrow
};
// Copies out of `t` are ok.
let (a, b) = (t.0, t.1);
c();
```

Similarly, taking the address of an unaligned field also captures the entire struct:

```rust,compile_fail,E0505
#[repr(packed)]
struct T(String, String);

let mut t = T(String::new(), String::new());
let c = || {
    let a = std::ptr::addr_of!(t.1); // captures `t` with ImmBorrow
};
let a = t.0; // ERROR: cannot move out of `t.0` because it is borrowed
c();
```

but the above works if it is not packed since it captures the field precisely:

```rust
struct T(String, String);

let mut t = T(String::new(), String::new());
let c = || {
    let a = std::ptr::addr_of!(t.1); // captures `t.1` with ImmBorrow
};
// The move here is allowed.
let a = t.0;
c();
```

[undefined behavior]: ../behavior-considered-undefined.md
[the `packed` representation]: ../type-layout.md#the-alignment-modifiers

r[type.closure.capture.precision.box-deref]
### `Box` vs other `Deref` implementations

The implementation of the [`Deref`] trait for [`Box`] is treated differently from other `Deref` implementations, as it is considered a special entity.

For example, let us look at examples involving `Rc` and `Box`. The `*rc` is desugared to a call to the trait method `deref` defined on `Rc`, but since `*box` is treated differently, it is possible to do a precise capture of the contents of the `Box`.

[`Box`]: ../special-types-and-traits.md#boxt
[`Deref`]: ../special-types-and-traits.md#deref-and-derefmut

r[type.closure.capture.precision.box-non-move.not-moved]
#### `Box` with non-`move` closure

In a non-`move` closure, if the contents of the `Box` are not moved into the closure body, the contents of the `Box` are precisely captured.

```rust
struct S(String);

let b = Box::new(S(String::new()));
let c_box = || {
    let x = &(*b).0; // captures `(*b).0` by ImmBorrow
};
c_box();

// Contrast `Box` with another type that implements Deref:
let r = std::rc::Rc::new(S(String::new()));
let c_rc = || {
    let x = &(*r).0; // captures `r` by ImmBorrow
};
c_rc();
```

r[type.closure.capture.precision.box-non-move.moved]
However, if the contents of the `Box` are moved into the closure, then the box is entirely captured. This is done so the amount of data that needs to be moved into the closure is minimized.

```rust
// This is the same as the example above except the closure
// moves the value instead of taking a reference to it.

struct S(String);

let b = Box::new(S(String::new()));
let c_box = || {
    let x = (*b).0; // captures `b` with ByValue
};
c_box();
```

r[type.closure.capture.precision.box-move.read]
#### `Box` with move closure

Similarly to moving contents of a `Box` in a non-`move` closure, reading the contents of a `Box` in a `move` closure will capture the `Box` entirely.

```rust
struct S(i32);

let b = Box::new(S(10));
let c_box = move || {
    let x = (*b).0; // captures `b` with ByValue
};
```

r[type.closure.unique-immutable]
## Unique immutable borrows in captures

Captures can occur by a special kind of borrow called a _unique immutable borrow_,
which cannot be used anywhere else in the language and cannot be written out explicitly.
It occurs when modifying the referent of a mutable reference, as in the following example:

```rust
let mut b = false;
let x = &mut b;
let mut c = || {
    // An ImmBorrow and a MutBorrow of `x`.
    let a = &x;
    *x = true; // `x` captured by UniqueImmBorrow
};
// The following line is an error:
// let y = &x;
c();
// However, the following is OK.
let z = &x;
```

In this case, borrowing `x` mutably is not possible, because `x` is not `mut`.
But at the same time, borrowing `x` immutably would make the assignment illegal,
because a `& &mut` reference might not be unique, so it cannot safely be used to modify a value.
So a unique immutable borrow is used: it borrows `x` immutably, but like a mutable borrow, it must be unique.

In the above example, uncommenting the declaration of `y` will produce an error because it would violate the uniqueness of the closure's borrow of `x`; the declaration of z is valid because the closure's lifetime has expired at the end of the block, releasing the borrow.

r[type.closure.call]
## Call traits and coercions

r[type.closure.call.intro]
Closure types all implement [`FnOnce`], indicating that they can be called once
by consuming ownership of the closure. Additionally, some closures implement
more specific call traits:

r[type.closure.call.fn-mut]
* A closure which does not move out of any captured variables implements
  [`FnMut`], indicating that it can be called by mutable reference.

r[type.closure.call.fn]
* A closure which does not mutate or move out of any captured variables
  implements [`Fn`], indicating that it can be called by shared reference.

> [!NOTE]
> `move` closures may still implement [`Fn`] or [`FnMut`], even though they capture variables by move. This is because the traits implemented by a closure type are determined by what the closure does with captured values, not how it captures them.

r[type.closure.non-capturing]
*Non-capturing closures* are closures that don't capture anything from their
environment. Non-async, non-capturing closures can be coerced to function pointers (e.g., `fn()`)
with the matching signature.

```rust
let add = |x, y| x + y;

let mut x = add(5,7);

type Binop = fn(i32, i32) -> i32;
let bo: Binop = add;
x = bo(5,7);
```

r[type.closure.async.traits]
### Async closure traits

r[type.closure.async.traits.fn-family]
Async closures have a further restriction of whether or not they implement [`FnMut`] or [`Fn`].

The [`Future`] returned by the async closure has similar capturing characteristics as a closure. It captures place expressions from the async closure based on how they are used. The async closure is said to be *lending* to its [`Future`] if it has either of the following properties:

- The `Future` includes a mutable capture.
- The async closure captures by value, except when the value is accessed with a dereference projection.

If the async closure is lending to its `Future`, then [`FnMut`] and [`Fn`] are *not* implemented. [`FnOnce`] is always implemented.

> **Example**: The first clause for a mutable capture can be illustrated with the following:
>
> ```rust,compile_fail
> fn takes_callback<Fut: Future>(c: impl FnMut() -> Fut) {}
>
> fn f() {
>     let mut x = 1i32;
>     let c = async || {
>         x = 2;  // x captured with MutBorrow
>     };
>     takes_callback(c);  // ERROR: async closure does not implement `FnMut`
> }
> ```
>
> The second clause for a regular value capture can be illustrated with the following:
>
> ```rust,compile_fail
> fn takes_callback<Fut: Future>(c: impl Fn() -> Fut) {}
>
> fn f() {
>     let x = &1i32;
>     let c = async move || {
>         let a = x + 2;  // x captured ByValue
>     };
>     takes_callback(c);  // ERROR: async closure does not implement `Fn`
> }
> ```
>
> The exception of the the second clause can be illustrated by using a dereference, which does allow `Fn` and `FnMut` to be implemented:
>
> ```rust
> fn takes_callback<Fut: Future>(c: impl Fn() -> Fut) {}
>
> fn f() {
>     let x = &1i32;
>     let c = async move || {
>         let a = *x + 2;
>     };
>     takes_callback(c);  // OK: implements `Fn`
> }
> ```

r[type.closure.async.traits.async-family]
Async closures implement [`AsyncFn`], [`AsyncFnMut`], and [`AsyncFnOnce`] in an analogous way as regular closures implement [`Fn`], [`FnMut`], and [`FnOnce`]; that is, depending on the use of the captured variables in its body.

r[type.closure.traits]
### Other traits

r[type.closure.traits.intro]
All closure types implement [`Sized`]. Additionally, closure types implement the
following traits if allowed to do so by the types of the captures it stores:

* [`Clone`]
* [`Copy`]
* [`Sync`]
* [`Send`]

r[type.closure.traits.behavior]
The rules for [`Send`] and [`Sync`] match those for normal struct types, while
[`Clone`] and [`Copy`] behave as if [derived]. For [`Clone`], the order of
cloning of the captured values is left unspecified.

Because captures are often by reference, the following general rules arise:

* A closure is [`Sync`] if all captured values are [`Sync`].
* A closure is [`Send`] if all values captured by non-unique immutable
  reference are [`Sync`], and all values captured by unique immutable or mutable
  reference, copy, or move are [`Send`].
* A closure is [`Clone`] or [`Copy`] if it does not capture any values by
  unique immutable or mutable reference, and if all values it captures by copy
  or move are [`Clone`] or [`Copy`], respectively.

[`Clone`]: ../special-types-and-traits.md#clone
[`Copy`]: ../special-types-and-traits.md#copy
[`Send`]: ../special-types-and-traits.md#send
[`Sized`]: ../special-types-and-traits.md#sized
[`Sync`]: ../special-types-and-traits.md#sync
[closure expression]: ../expressions/closure-expr.md
[derived]: ../attributes/derive.md

r[type.closure.drop-order]
## Drop order

If a closure captures a field of a composite types such as structs, tuples, and enums by value, the field's lifetime would now be tied to the closure. As a result, it is possible for disjoint fields of a composite types to be dropped at different times.

```rust
{
    let tuple =
      (String::from("foo"), String::from("bar")); // --+
    { //                                               |
        let c = || { // ----------------------------+  |
            // tuple.0 is captured into the closure |  |
            drop(tuple.0); //                       |  |
        }; //                                       |  |
    } // 'c' and 'tuple.0' dropped here ------------+  |
} // tuple.1 dropped here -----------------------------+
```

r[type.closure.capture.precision.edition2018.entirety]
## Edition 2018 and before

### Closure types difference

In Edition 2018 and before, closures always capture a variable in its entirety, without its precise capture path. This means that for the example used in the [Closure types](#closure-types) section, the generated closure type would instead look something like this:

<!-- ignore: simplified -->
```rust,ignore
struct Closure<'a> {
    rect : &'a mut Rectangle,
}

impl<'a> FnOnce<()> for Closure<'a> {
    type Output = String;
    extern "rust-call" fn call_once(self, args: ()) -> String {
        self.rect.left_top.x += 1;
        self.rect.right_bottom.x += 1;
        format!("{:?}", self.rect.left_top)
    }
}
```

and the call to `f` would work as follows:

<!-- ignore: continuation of above -->
```rust,ignore
f(Closure { rect: rect });
```

r[type.closure.capture.precision.edition2018.composite]
### Capture precision difference

Composite types such as structs, tuples, and enums are always captured in its entirety,
not by individual fields. As a result, it may be necessary to borrow into a local variable in order to capture a single field:

```rust
# use std::collections::HashSet;
#
struct SetVec {
    set: HashSet<u32>,
    vec: Vec<u32>
}

impl SetVec {
    fn populate(&mut self) {
        let vec = &mut self.vec;
        self.set.iter().for_each(|&n| {
            vec.push(n);
        })
    }
}
```

If, instead, the closure were to use `self.vec` directly, then it would attempt to capture `self` by mutable reference. But since `self.set` is already borrowed to iterate over, the code would not compile.

r[type.closure.capture.precision.edition2018.move]
If the `move` keyword is used, then all captures are by move or, for `Copy` types, by copy, regardless of whether a borrow would work. The `move` keyword is usually used to allow the closure to outlive the captured values, such as if the closure is being returned or used to spawn a new thread.

r[type.closure.capture.precision.edition2018.wildcard]
Regardless of if the data will be read by the closure, i.e. in case of wild card patterns, if a variable defined outside the closure is mentioned within the closure the variable will be captured in its entirety.

r[type.closure.capture.precision.edition2018.drop-order]
### Drop order difference

As composite types are captured in their entirety, a closure which captures one of those composite types by value would drop the entire captured variable at the same time as the closure gets dropped.

```rust
{
    let tuple =
      (String::from("foo"), String::from("bar"));
    {
        let c = || { // --------------------------+
            // tuple is captured into the closure |
            drop(tuple.0); //                     |
        }; //                                     |
    } // 'c' and 'tuple' dropped here ------------+
}
```
