]> git.lizzy.rs Git - rust.git/commit
Special-case `Box` in `rustc_mir::borrow_check`.
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Thu, 26 Jul 2018 20:29:50 +0000 (22:29 +0200)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Wed, 1 Aug 2018 15:41:32 +0000 (17:41 +0200)
commitc3618c8b2e87d58fc5e8f18f5a2f8801e29c01e7
treee23dfb306c5069d26b4c3719a177472293fc01aa
parent11f812aa7d1df09724f94c2b095f6dbfd367da17
Special-case `Box` in `rustc_mir::borrow_check`.

This should address issue 45696.

Since we know dropping a box will not access any `&mut` or `&`
references, it is safe to model its destructor as only touching the
contents *owned* by the box.

Note: At some point we may want to generalize this machinery to other
reference and collection types that are "pure" in the same sense as
box. If we add a `&move` reference type, it would probably also fall
into this branch of code. But for the short term, we will be
conservative and restrict this change to `Box<T>` alone.

The code works by recursively descending a deref of the `Box`. We
prevent `visit_terminator_drop` infinite-loop (which can arise in a
very obscure scenario) via a linked-list of seen types.

Note: A similar style stack-only linked-list definition can be found
in `rustc_mir::borrow_check::places_conflict`. It might be good at
some point in the future to unify the two types and put the resulting
definition into `librustc_data_structures/`.

----

One final note: Review feedback led to significant simplification of
logic here.

During review, eddyb RalfJung and I uncovered the heart of why I
needed a so-called "step 2" aka the Shallow Write to the Deref of the
box. It was because the `visit_terminator_drop`, in its base case,
will not emit any write at all (shallow or deep) to a place unless
that place has a need_drop.

So I was encoding a Shallow Write by hand for a `Box<T>`, as a
separate step from recursively descending through `*a_box` (which was
at the time known as "step 1"; it is now the *only* step, apart from
the change to the base case for `visit_terminator_drop` that this
commit now has encoded).

eddyb aruged that *something* should be emitting some sort of write in
the base case here (even a shallow one), of the dropped place, since
by analogy we also emit a write when you *move* a place. That led
to the revision here in this commit.

 * (Its possible that this desired write should be attached in some
   manner to StorageDead instead of Drop. But in this PR, I tried to
   leave the StorageDead logic alone and focus my attention solely on
   how Drop(x) is modelled in MIR-borrowck.)
src/librustc_mir/borrow_check/mod.rs