1357 Commits

Author SHA1 Message Date
Niko Matsakis
0d6bd42abb make blame_span deterministic 2017-12-15 10:27:54 -05:00
Niko Matsakis
e9824c50ed impose inputs/ouputs on MIR after the fact
The input/output types found in `UniversalRegions` are not normalized.
The old code used to assign them directly into the MIR, which would
lead to errors when there was a projection in a argument or return
type. This also led to some special cases in the `renumber` code.

We now renumber uniformly but then pass the input/output types into
the MIR type-checker, which equates them with the types found in MIR.
This allows us to normalize at the same time.
2017-12-15 10:27:53 -05:00
Niko Matsakis
3fcb13ae45 handle projections with regions 2017-12-15 10:27:52 -05:00
Niko Matsakis
3a5842afe1 add a new RegionKind variant: ReClosureBound
This is needed to allow the `ClosureRegionRequirements` to capture
types that include regions.
2017-12-15 10:27:52 -05:00
Niko Matsakis
85e1d4749e propagate type tests from closure to closure creators
Currently, we only propagate type tests that exclude all regions from
the type.
2017-12-15 10:27:51 -05:00
Niko Matsakis
5804637a81 permit ClosureOutlivesRequirement to constrain regions or types 2017-12-15 10:27:51 -05:00
Niko Matsakis
c7cfa2367b thread through an implicit region body of the fn body 2017-12-15 10:27:50 -05:00
Niko Matsakis
02e65250e4 mild refactors of the control flow (no functional changes)
In the future, `check_type_tests` will also potentially propagate
constriants to its caller.
2017-12-15 10:27:49 -05:00
Niko Matsakis
47c1921b9a move some parts of liveness to happen during type checking
This allows us to re-use the `normalize` method on `TypeCheck`, which
is important since normalization may create fresh region
variables. This is not an ideal solution, though, since the current
representation of "liveness constraints" (a vector of (region, point)
pairs) is rather inefficient. Could do somewhat better by converting
to indices, but it'd still be less good than the older code. Unclear
how important this is.
2017-12-15 10:27:49 -05:00
Niko Matsakis
4a940b3215 move flow_in_progress into dataflow and document it 2017-12-15 10:27:46 -05:00
Niko Matsakis
ebd086b67f move LivenessResults from nll into liveness analysis 2017-12-15 10:10:57 -05:00
Niko Matsakis
1c57468840 move type_check out of transform and into the nll module 2017-12-15 10:10:57 -05:00
Niko Matsakis
fad3d1d7fd dfs.rs: rustfmt 2017-12-15 10:10:56 -05:00
Niko Matsakis
6193c5cc2a translate Verifys into TypeTests and check them 2017-12-15 10:10:56 -05:00
Niko Matsakis
cd564d20ff only propagate ClosureRegionRequirements if non-trivial
Before, we would always have a `Some` ClosureRegionRequirements if we
were inferring values for a closure. Now we only do is it has a
non-empty set of outlives requirements.
2017-12-15 10:10:56 -05:00
Niko Matsakis
a0f0392a6d rename copy to dfs and make it customizable 2017-12-15 10:10:55 -05:00
Niko Matsakis
86334c7116 remove unnecessary intermediate vector from copy 2017-12-15 10:10:55 -05:00
bors
84feab34e4 Auto merge of #46537 - pnkfelix:two-phase-borrows, r=arielb1
[MIR-borrowck] Two phase borrows

This adds limited support for two-phase borrows as described in
  http://smallcultfollowing.com/babysteps/blog/2017/03/01/nested-method-calls-via-two-phase-borrowing/

The support is off by default; you opt into it via the flag `-Z two-phase-borrows`

I have written "*limited* support" above because there are simple variants of the simple `v.push(v.len())` example that one would think should work but currently do not, such as the one documented in the test compile-fail/borrowck/two-phase-reservation-sharing-interference-2.rs

(To be clear, that test is not describing something that is unsound. It is just providing an explicit example of a limitation in the implementation given in this PR. I have ideas on how to fix, but I want to land the work that is in this PR first, so that I can stop repeatedly rebasing this branch.)
2017-12-15 05:40:12 +00:00
Felix S. Klock II
159037e053 Address review feedback: don't treat "first" activation special.
Instead, filter out (non-)conflicts of activiations with themselves in
the same manner that we filter out non-conflict between an activation
and its reservation.
2017-12-14 17:34:16 -06:00
Felix S. Klock II
b0421fa7de Address review feedback: don't bother skipping reservations paired with activations. 2017-12-14 16:28:26 -06:00
bors
2974104276 Auto merge of #45002 - oli-obk:miri, r=eddyb
Validate miri against the HIR const evaluator

r? @eddyb

cc @alexcrichton @arielb1 @RalfJung

The interesting parts are the last few functions in `librustc_const_eval/eval.rs`

* We warn if miri produces an error while HIR const eval does not.
* We warn if miri produces a value that does not match the value produced by HIR const eval
* if miri succeeds and HIR const eval fails, nothing is emitted, but we still return the HIR error
* if both error, nothing is emitted and the HIR const eval error is returned

So there are no actual changes, except that miri is forced to produce the same values as the old const eval.

* This does **not** touch the const evaluator in trans at all. That will come in a future PR.
* This does **not** cause any code to compile that didn't compile before. That will also come in the future

It would be great if someone could start a crater run if travis passes
2017-12-14 15:37:39 +00:00
Felix S. Klock II
b75248ef4e Address review note: AccessErrorsReported meant to track whether error reported at *any* point in past. 2017-12-14 09:03:04 -06:00
Oliver Schneider
1ba46dc378
Move mir validation out of tree 2017-12-14 11:36:28 +01:00
Felix S. Klock II
f96777c9ff After discussion with ariel, replacing a guard within kill_loans_out_of_scope_at_location.
Instead we are "just" careful to invoke it (which sets up a bunch of kill bits)
before we go into the code that sets up the gen bits.

That way, when the gen bits are set up, they will override any
previously set kill-bits for those reservations or activations.
2017-12-13 18:10:37 -06:00
Felix S. Klock II
3c7d9ff90a Address review comment: use .get instead of indexing to cope w/ terminators.
(Same net effect as code from before; just cleaner way to get there.)
2017-12-13 18:07:02 -06:00
Felix S. Klock II
5cae7a0469 Check activation points as the place where mutable borrows become relevant.
Since we are now checking activation points, I removed one of the
checks at the reservation point. (You can see the effect this had on
two-phase-reservation-sharing-interference-2.rs)

Also, since we now have checks at both the reservation point and the
activation point, we sometimes would observe duplicate errors (since
either one independently interferes with another mutable borrow).  To
deal with this, I used a similar strategy to one used as discussed on
issue #45360: keep a set of errors reported (in this case for
reservations), and then avoid doing the checks for the corresponding
activations. (This does mean that some errors could get masked, namely
for conflicting borrows that start after the reservation but still
conflict with the activation, which is unchecked when there was an
error for the reservation. But this seems like a reasonable price to
pay.)
2017-12-13 15:48:21 -06:00
Felix S. Klock II
18aedf6b23 Sidestep ICE from MirBorrowckCtxt::find_closure_span. 2017-12-13 15:48:21 -06:00
Felix S. Klock II
36216456a6 Incorporate active-borrows dataflow into MIR borrow check, yielding
two-phase `&mut`-borrow support.

This (new) support sits under `-Z two-phase-borrows` debugflag.

(Still needs tests. That's coming next.)
2017-12-13 15:48:20 -06:00
Felix S. Klock II
1334638144 Add some doc to struct Borrows. 2017-12-13 15:48:20 -06:00
Felix S. Klock II
658ed79700 Add some doc to each_borrow_involving_path iteration function. 2017-12-13 15:48:20 -06:00
Felix S. Klock II
ced5a701ff New ActiveBorrows dataflow for two-phase &mut; not yet borrowed-checked.
High-level picture: The old `Borrows` analysis is now called
`Reservations` (implemented as a newtype wrapper around `Borrows`);
this continues to compute whether a `Rvalue::Ref` can reach a
statement without an intervening `EndRegion`. In addition, we also
track what `Place` each such `Rvalue::Ref` was immediately assigned
to in a given borrow (yay for MIR-structural properties!).

The new `ActiveBorrows` analysis then tracks the initial use of any of
those assigned `Places` for a given borrow. I.e. a borrow becomes
"active" immediately after it starts being "used" in some way. (This
is conservative in the sense that we will treat a copy `x = y;` as a
use of `y`; in principle one might further delay activation in such
cases.)

The new `ActiveBorrows` analysis needs to take the `Reservations`
results as an initial input, because the reservation state influences
the gen/kill sets for `ActiveBorrows`. In particular, a use of `a`
activates a borrow `a = &b` if and only if there exists a path (in the
control flow graph) from the borrow to that use. So we need to know if
the borrow reaches a given use to know if it really gets a gen-bit or
not.

 * Incorporating the output from one dataflow analysis into the input
   of another required more changes to the infrastructure than I had
   expected, and even after those changes, the resulting code is still
   a bit subtle.

 * In particular, Since we need to know the intrablock reservation
   state, we need to dynamically update a bitvector for the
   reservations as we are also trying to compute the gen/kills
   bitvector for the active borrows.

 * The way I ended up deciding to do this (after also toying with at
   least two other designs) is to put both the reservation state and
   the active borrow state into a single bitvector. That is why we now
   have separate (but related) `BorrowIndex` and
   `ReserveOrActivateIndex`: each borrow index maps to a pair of
   neighboring reservation and activation indexes.

As noted above, these changes are solely adding the active borrows
dataflow analysis (and updating the existing code to cope with the
switch from `Borrows` to `Reservations`). The code to process the
bitvector in the borrow checker currently just skips over all of the
active borrow bits.

But atop this commit, one *can* observe the analysis results by
looking at the graphviz output, e.g. via

```rust
 #[rustc_mir(borrowck_graphviz_preflow="pre_two_phase.dot",
             borrowck_graphviz_postflow="post_two_phase.dot")]
```

Includes doc for `FindPlaceUses`, as well as `Reservations` and
`ActiveBorrows` structs, which are wrappers are the `Borrows` struct
that dictate which flow analysis should be performed.
2017-12-13 15:48:15 -06:00
Felix S. Klock II
39e126c001 Refactoring alpha-rename place (BorrowData field) to borrowed_place. 2017-12-13 13:50:40 -06:00
Felix S. Klock II
e123117cb7 Refactoring: Allow BlockSets.on_entry to denote locally accumulated intrablock state.
(Still musing about whether it could make sense to revise the design
here to make these constraints on usage explicit.)
2017-12-13 13:50:39 -06:00
Felix S. Klock II
d4add5d52a Refactoring: pull bitvector initialization out from other parts of dataflow.
This is meant to ease development of multi-stage dataflow analyses
where the output from one analysis is used to initialize the state
for the next; in such a context, you cannot start with `bottom_value`
for all the bits.
2017-12-13 13:50:39 -06:00
Niko Matsakis
51847a1b18 add FIXME related to constant well-formedness 2017-12-13 12:20:28 -05:00
Niko Matsakis
abd6d0d76e comments for defining_ty and compute_indices
Plus an extra assertion.
2017-12-13 12:20:28 -05:00
Niko Matsakis
75ac071cd6 document return value of add_live_point 2017-12-13 12:20:28 -05:00
Niko Matsakis
7a20a3f161 change to use an O(1) data structure for looking up point indices
Converting a `RegionElementIndex` to a `Location` is O(n) though could
trivially be O(log n), but we don't do it that much anyhow -- just on
error and debugging.
2017-12-13 12:20:28 -05:00
Niko Matsakis
77663a677d refactor region value bitmatrix 2017-12-13 12:20:27 -05:00
Niko Matsakis
d5cff0740f normalize fn sig as part of reification 2017-12-13 06:03:28 -05:00
Santiago Pastorino
0c26d8fcd1 Mir typeck Cast for Unsize value 2017-12-13 06:03:28 -05:00
Santiago Pastorino
14700e58b4 Mir typeck Cast for ClosureFnPtr value 2017-12-13 06:03:27 -05:00
Santiago Pastorino
900d4d5bda Mir typeck Cast for UnsafeFnPtr value 2017-12-13 06:03:27 -05:00
Santiago Pastorino
7d56131e83 Mir typeck Cast for ReifyFnPtr value 2017-12-13 06:03:27 -05:00
Santiago Pastorino
86355480bd Restructure a bit check_aggregate_rvalue code 2017-12-13 06:03:27 -05:00
Santiago Pastorino
4449240d1e Add more debug logs 2017-12-13 06:03:26 -05:00
Santiago Pastorino
688ab5af81 Check functions predicates 2017-12-13 06:03:26 -05:00
Santiago Pastorino
5010496677 Check Aggregate predicates 2017-12-13 06:03:26 -05:00
Santiago Pastorino
c9159262d1 Check NullaryOp Rvalue 2017-12-13 06:03:26 -05:00
Niko Matsakis
7f20b9142d fix universal regions to handle constant expressions like [T; 22] 2017-12-13 06:03:25 -05:00