Home Explore Blog CI



rustc

3rd chunk of `src/borrow_check/drop_check.md`
4f952c2ee119c9a46692bddfc750b6113409d32ca30d9f7b0000000100000bf1
        drop(x);
    }
} //~ ERROR `temp` does not live long enough.
```

It should be possible to add some amount of drop elaboration before
borrowck, allowing this example to compile. There is an unstable feature
to move drop elaboration before const checking:
[#73255](https://github.com/rust-lang/rust/issues/73255). Such a feature
gate does not exist for doing some drop elaboration before borrowck,
although there's a [relevant
MCP](https://github.com/rust-lang/compiler-team/issues/558).

implementation which directly uses the `drop_in_place` provided by the
vtable. This `Drop` implementation requires all its generic parameters
to be live.

### `dropck_outlives`

There are two distinct "liveness" computations that we perform:

* a value `v` is *use-live* at location `L` if it may be "used" later; a
  *use* here is basically anything that is not a *drop*
* a value `v` is *drop-live* at location `L` if it maybe dropped later

When things are *use-live*, their entire type must be valid at `L`. When
they are *drop-live*, all regions that are required by dropck must be
valid at `L`.  The values dropped in the MIR are *places*.

The constraints computed by `dropck_outlives` for a type closely match
the generated drop glue for that type. Unlike drop glue,
`dropck_outlives` cares about the types of owned values, not the values
itself. For a value of type `T`

- if `T` has an explicit `Drop`, require all generic arguments to be
  live, unless they are marked with `#[may_dangle]` in which case they
  are fully ignored
- regardless of whether `T` has an explicit `Drop`, recurse into all
  types *owned* by `T`
    - references, raw pointers, function pointers, function items, trait
      objects[^traitobj], and scalars do not own anything.
    - tuples, slices and arrays consider their element type to be owned.
      **For arrays we currently do not check whether their length is
      zero**.
    - all fields (of all variants) of ADTs are considered owned. The
      exception here is `ManuallyDrop<U>` which is not considered to own
      `U`. **We consider `PhantomData<U>` to own `U`**.
    - closures and generators own their captured upvars.

The sections marked in bold are cases where `dropck_outlives` considers
types to be owned which are ignored by `Ty::needs_drop`. We only rely on
`dropck_outlives` if `Ty::needs_drop` for the containing local returned
`true`.This means liveness requirements can change depending on whether
a type is contained in a larger local. **This is inconsistent, and
should be fixed: an example [for
arrays](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=8b5f5f005a03971b22edb1c20c5e6cbe)
and [for
`PhantomData`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=44c6e2b1fae826329fd54c347603b6c8).**[^core]

One possible way these inconsistencies can be fixed is by MIR building
to be more pessimistic, probably by making `Ty::needs_drop` weaker, or
alternatively, changing `dropck_outlives` to be more precise, requiring
fewer regions to be live.


Title: `dropck_outlives` and Liveness Computations in Rust
Summary
This section explains `dropck_outlives` and distinguishes between use-liveness and drop-liveness. It describes how `dropck_outlives` computes constraints for a type, closely matching the generated drop glue. The process recurses into owned types. It then highlights inconsistencies where `dropck_outlives` considers types to be owned when `Ty::needs_drop` does not, leading to inconsistent liveness requirements depending on the container. The inconsistencies can be fixed by making MIR building more pessimistic or by making `dropck_outlives` more precise.