Whenever there is a closure expression, we need to determine how each
upvar is used. We do this by initially assigning each upvar an
immutable “borrow kind” (see
ty::BorrowKind for details) and then
“escalating” the kind as needed. The borrow kind proceeds according to
the following lattice:
ty::ImmBorrow -> ty::UniqueImmBorrow -> ty::MutBorrow
So, for example, if we see an assignment
x = 5 to an upvar
will promote its borrow kind to mutable borrow. If we see an
we’ll do the same. Naturally, this applies not just to the upvar, but
to everything owned by
x, so the result is the same for something
x.f = 5 and so on (presuming
x is not a borrowed pointer to a
struct). These adjustments are performed in
adjust_upvar_borrow_kind() (you can trace backwards through the code
The fact that we are inferring borrow kinds as we go results in a
semi-hacky interaction with mem-categorization. In particular,
mem-categorization will query the current borrow kind as it
categorizes, and we’ll return the current value, but this may get
adjusted later. Therefore, in this module, we generally ignore the
borrow kind (and derived mutabilities) that are returned from
mem-categorization, since they may be inaccurate. (Another option
would be to use a unification scheme, where instead of returning a
concrete borrow kind like
ty::ImmBorrow, we return a
ty::InferBorrow(upvar_id) or something like that, but this would
then mean that all later passes would have to check for these figments
and report an error, and it just seems like more mess in the end.)
- Intermediate format to store information needed to generate a note in the migration lint.
- Reasons that we might issue a migration warning.
- Intermediate format to store the hir id of the root variable and a HashSet containing information on why the root variable should be fully captured
- Describe the relationship between the paths of two places eg:
- Intermediate format to store the hir_id pointing to the use that resulted in the corresponding place being captured and a String which contains the captured value’s name (i.e: a.b.c)
- Truncate deref of any reference.
- Adjust closure capture just that if taking ownership of data, only move data from enclosing stack frame.
- Returns a Ty that applies the specified capture kind on the provided capture Ty
- Helper function to determine if we need to escalate CaptureKind from CaptureInfo A to B and returns the escalated CaptureInfo. (Note: CaptureInfo contains CaptureKind and an expression that led to capture it in that way)
- Determines the Ancestry relationship of Place A relative to Place B
- Returns the Span of where the value with the provided HirId would be dropped
- Precise capture is enabled if user is using Rust Edition 2021 or higher.
spanis the span of the closure.
- Return a two string tuple (s1, s2)
- Truncate projections so that following rules are obeyed by the captured
- Rust doesn’t permit moving fields out of a type that implements drop
placeso that an
unsafeblock isn’t required to capture it.
- Truncate the capture so that the place being borrowed is in accordance with RFC 1240, which states that it’s unsafe to take a reference into a struct marked
- Reduces the precision of the captured place when the precision doesn’t yield any benefit from borrow checking perspective, allowing us to save us on the size of the capture.
placeto have up to
curr_modeis the current required capture kind for the place. Returns the truncated
placeand the updated required capture kind.
- var_name 🔒
- Intermediate format to store a captured
ty::CaptureInfoduring capture analysis. Information in this map feeds into the minimum capture analysis pass.