161 Commits

Author SHA1 Message Date
bors
9a20bfc856 Auto merge of #31465 - nagisa:mir-free-fix, r=nikomatsakis
Fixes #31463
2016-02-10 04:34:15 +00:00
Oliver Schneider
030b237476 refactor MirPass to always require a tcx 2016-02-09 16:53:42 +01:00
Oliver Schneider
41c892f5e1 make MirMap a struct instead of a type alias for NodeMap 2016-02-09 16:53:42 +01:00
bors
efdde2479b Auto merge of #31324 - nagisa:mir-transforms, r=nikomatsakis
Having a `MirPass` provides literally no benefits over `MutVisitor`. Moreover using `MirPass` for
`EraseRegions` basically makes the programmer to fix breakage from changing repr twice – in the
visitor and eraseregions. Since `MutVisitor` implements all the “walking” inside the trait, that can
be reused for `EraseRegions` too, basically resulting in less code duplication.
2016-02-08 19:04:25 +00:00
Simonas Kazlauskas
ae151d3945 [MIR] Fix the destination of implicit else branch 2016-02-07 21:47:23 +02:00
Simonas Kazlauskas
7faaf0e2de Do not forget to drop the boxes on scope exits
Fixes #31463
2016-02-07 18:03:15 +02:00
Simonas Kazlauskas
0b3ef97066 Reuse MIR visitors for EraseRegions pass 2016-02-06 12:56:52 +02:00
Simonas Kazlauskas
5638847ae3 Address nits on build/scope.rs 2016-02-04 15:56:05 +02:00
Simonas Kazlauskas
98265d3385 Convert Drop statement into terminator
The structure of the old translator as well as MIR assumed that drop glue cannot possibly panic and
translated the drops accordingly. However, in presence of `Drop::drop` this assumption can be
trivially shown to be untrue. As such, the Rust code like the following would never print number 2:

```rust
struct Droppable(u32);
impl Drop for Droppable {
    fn drop(&mut self) {
        if self.0 == 1 { panic!("Droppable(1)") } else { println!("{}", self.0) }
    }
}
fn main() {
    let x = Droppable(2);
    let y = Droppable(1);
}
```

While the behaviour is allowed according to the language rules (we allow drops to not run), that’s
a very counter-intuitive behaviour. We fix this in MIR by allowing `Drop` to have a target to take
on divergence and connect the drops in such a way so the leftover drops are executed when some drop
unwinds.

Note, that this commit still does not implement the translator part of changes necessary for the
grand scheme of things to fully work, so the actual observed behaviour does not change yet. Coming
soon™.

See #14875.
2016-02-04 15:56:05 +02:00
Simonas Kazlauskas
65dd5e6a84 Remove the CallKind
We used to have CallKind only because there was a requirement to have all successors in a
contiguous memory block. Now that the requirement is gone, remove the CallKind and instead just
have the necessary information inline.

Awesome!
2016-02-04 15:56:04 +02:00
Simonas Kazlauskas
02365fe753 Change successor{,_mut} to return a Vec
This helps to avoid the unpleasant restriction of being unable to have multiple successors in
non-contiguous block of memory.
2016-02-04 15:56:04 +02:00
Simonas Kazlauskas
432460a6fc Synthesize calls to box_free language item
This gets rid of Drop(Free, _) MIR construct by synthesizing a call to language item which
takes care of dropping instead.
2016-02-04 15:56:01 +02:00
Oliver Schneider
4e44ef1e29 upgrade comments on MIR structures and functions to doc comments 2016-02-03 13:25:07 +01:00
Oliver Schneider
06ef2e72c9 [MIR] Fix type of temporary for box EXPR
Previously the code would fail to dereference the temporary.
2016-01-29 16:13:31 +01:00
Alex Crichton
4b3c35509b rustc_mir: Mark the crate as unstable
Wouldn't want to be able to link to this on stable Rust!
2016-01-24 20:35:55 -08:00
Alex Crichton
2273b52023 mk: Move from -D warnings to #![deny(warnings)]
This commit removes the `-D warnings` flag being passed through the makefiles to
all crates to instead be a crate attribute. We want these attributes always
applied for all our standard builds, and this is more amenable to Cargo-based
builds as well.

Note that all `deny(warnings)` attributes are gated with a `cfg(stage0)`
attribute currently to match the same semantics we have today
2016-01-24 20:35:55 -08:00
Florian Hahn
9884ff1dfb Add Debug impl and erase region for TypedConstVal 2016-01-21 22:53:00 +01:00
Florian Hahn
d31027d3bf Introduce and use TypedConstVal for Repeat 2016-01-21 22:47:11 +01:00
Florian Hahn
c78609134c [MIR] use mir::repr::Constant in ExprKind::Repeat, close #29789 2016-01-21 22:46:50 +01:00
bors
51108b64ca Auto merge of #31010 - petrochenkov:def, r=arielb1
All structs and their constructors are defined as `DefStruct`.
`DefTy` is splitted into `DefEnum` and `DefTyAlias`.
Ad hoc flag `bool is_structure` is removed from `DefVariant`, it was required in one place in resolve and could be obtained by other means.
Flag `bool is_ctor` is removed from `DefFn`, it wasn't really used for constructors outside of metadata decoding.

Observable effects:
More specific error messages are selected in some cases.
Two name resolution bugs fixed (https://github.com/rust-lang/rust/issues/30992 and FIXME in compile-fail/empty-struct-braces-expr.rs).

Fixes https://github.com/rust-lang/rust/issues/30992
Closes https://github.com/rust-lang/rust/issues/30361
2016-01-21 01:43:18 +00:00
bors
4bb9d453cf Auto merge of #30945 - nagisa:mir-optional-block-dest, r=nikomatsakis
As an attempt to make loop body destination be optional, author implemented a pretty self contained
change and deemed it to be (much) uglier than the alternative of just keeping the unit temporary.
Having the temporary created lazily also has a nice property of not figuring in the MIR of
functions which do not use loops of any sort.

r? @nikomatsakis
2016-01-20 22:03:33 +00:00
Vadim Petrochenkov
2084c2c33a Rename Def's variants and don't reexport them 2016-01-20 22:31:10 +03:00
Vadim Petrochenkov
ceaaa1bc33 Refactor definitions of ADTs in rustc::middle::def 2016-01-20 21:50:57 +03:00
Simonas Kazlauskas
f9f6e3ad10 [MIR] Reintroduce the unit temporary
An attempt to make loop body destination be optional, author implemented a pretty self contained
change and deemed it to be (much) uglier than the alternative of just keeping the unit temporary.
Having the temporary created lazily also has a nice property of not figuring in the MIR of
functions which do not use loops of any sort.
2016-01-19 22:53:34 +02:00
bors
c14b615534 Auto merge of #30533 - nikomatsakis:fulfillment-tree, r=aturon
This PR introduces an `ObligationForest` data structure that the fulfillment context can use to track what's going on, instead of the current flat vector. This enables a number of improvements:

1. transactional support, at least for pushing new obligations
2. remove the "errors will be reported" hack -- instead, we only add types to the global cache once their entire subtree has been proven safe. Before, we never knew when this point was reached because we didn't track the subtree.
   - this in turn allows us to limit coinductive reasoning to structural traits, which sidesteps #29859
3. keeping the backtrace should allow for an improved error message, where we give the user full context
    - we can also remove chained obligation causes

This PR is not 100% complete. In particular:

- [x] Currently, types that embed themselves like `struct Foo { f: Foo }` give an overflow when evaluating whether `Foo: Sized`. This is not a very user-friendly error message, and this is a common beginner error. I plan to special-case this scenario, I think.
- [x] I should do some perf. measurements. (Update: 2% regression.)
- [x] More tests targeting #29859
- [ ] The transactional support is not fully integrated, though that should be easy enough.
- [ ] The error messages are not taking advantage of the backtrace.

I'd certainly like to do 1 through 3 before landing, but 4 and 5 could come as separate PRs.

r? @aturon // good way to learn more about this part of the trait system
f? @arielb1 // already knows this part of the trait system :)
2016-01-16 16:03:22 +00:00
Niko Matsakis
20e088c4e2 fallout from removing the errors_will_be_reported flag 2016-01-16 05:22:32 -05:00
bors
683af0d9e0 Auto merge of #30446 - michaelwu:associated-const-type-params-pt1, r=nikomatsakis
This provides limited support for using associated consts on type parameters. It generally works on things that can be figured out at trans time. This doesn't work for array lengths or match arms. I have another patch to make it work in const expressions.

CC @eddyb @nikomatsakis
2016-01-15 21:33:58 +00:00
Simonas Kazlauskas
4b17e2b71a Generate ADTs for tuple-like constructors instead
Previously we would generate regular calls for these, which is likely to result in worse LLVM code,
especially in presence of cleanups – we needn’t unecessarilly generate landing pads to construct an
ADT!
2016-01-15 18:06:49 +02:00
Michael Wu
a4f91e5fed Support generic associated consts 2016-01-14 17:35:55 -05:00
bors
d6cb2791ce Auto merge of #30635 - nagisa:mir-rid-unit-temp, r=nikomatsakis
Get rid of that nasty unit_ty temporary variable created just because it might be handy to have one around, when in reality it isn’t really that useful at all.

r? @nikomatsakis

Fixes https://github.com/rust-lang/rust/issues/30637
2016-01-12 05:20:23 +00:00
Simonas Kazlauskas
584e145e43 Rollup merge of #30798 - erickt:fix-doc, r=apasel422 2016-01-11 21:17:53 +02:00
Simonas Kazlauskas
04906061d8 Rollup merge of #30761 - nagisa:mir-fix-destination, r=michaelwoerister
Previously it was returning a clone, mostly for the two reasons:

* Cloning Lvalue is very cheap most of the time (i.e. when Lvalue is not a Projection);
* There’s users who want &mut lvalue and there’s users who want &lvalue. Returning a value allows
  to make either one easier when pattern matching (i.e. Some(ref dest) or Some(ref mut dest)).

However, I’m now convinced this is an invalid approach. Namely the users which want a mutable
reference may modify the Lvalue in-place, but the changes won’t be reflected in the final MIR,
since the Lvalue modified is merely a clone.

Instead, we have two accessors `destination` and `destination_mut` which return a reference to the
destination in desired mode.

r? @nikomatsakis
2016-01-11 21:17:52 +02:00
Erick Tryzelaar
cd1f0b75f3 Fix a typo in rustc_mir::build::scope's documentation 2016-01-09 10:31:50 -08:00
Simonas Kazlauskas
2f86c1605c Change destination accessor to return references
Previously it was returning a value, mostly for the two reasons:

* Cloning Lvalue is very cheap most of the time (i.e. when Lvalue is not a Projection);
* There’s users who want &mut lvalue and there’s users who want &lvalue. Returning a value allows
  to make either one easier when pattern matching (i.e. Some(ref dest) or Some(ref mut dest)).

However, I’m now convinced this is an invalid approach. Namely the users which want a mutable
reference may modify the Lvalue in-place, but the changes won’t be reflected in the final MIR,
since the Lvalue modified is merely a clone.

Instead, we have two accessors `destination` and `destination_mut` which return a reference to the
destination in desired mode.
2016-01-08 14:40:32 +02:00
Scott Olson
8e293676ee Fix MIR text output for terminators since they were made optional. 2016-01-07 15:16:07 -06:00
Simonas Kazlauskas
3692ab673e [MIR] Set dest ∀ expr with optional value
Assign a default unit value to the destinations of block expressions without trailing expression,
return expressions without return value (i.e. `return;`) and conditionals without else clause.
2016-01-07 02:12:36 +02:00
Simonas Kazlauskas
15096371dc [MIR] Get rid of that nasty unit_ty temporary lval 2016-01-06 21:43:58 +02:00
bors
e8c337b5ca Auto merge of #30532 - nikomatsakis:cross-item-dependencies, r=mw
This is roughly the same as my previous PR that created a dependency graph, but that:

1. The dependency graph is only optionally constructed, though this doesn't seem to make much of a difference in terms of overhead (see measurements below).
2. The dependency graph is simpler (I combined a lot of nodes).
3. The dependency graph debugging facilities are much better: you can now use `RUST_DEP_GRAPH_FILTER` to filter the dep graph to just the nodes you are interested in, which is super help.
4. The tests are somewhat more elaborate, including a few known bugs I need to fix in a second pass.

This is potentially a `[breaking-change]` for plugin authors. If you are poking about in tcx state or something like that, you probably want to add `let _ignore = tcx.dep_graph.in_ignore();`, which will cause your reads/writes to be ignored and not affect the dep-graph.

After this, or perhaps as an add-on to this PR in some cases, what I would like to do is the following:

- [x] Write-up a little guide to how to use this system, the debugging options available, and what the possible failure modes are.
- [ ] Introduce read-only and perhaps the `Meta` node
- [x] Replace "memoization tasks" with node from the map itself
- [ ] Fix the shortcomings, obviously! Notably, the HIR map needs to register reads, and there is some state that is not yet tracked. (Maybe as a separate PR.)
- [x] Refactor the dep-graph code so that the actual maintenance of the dep-graph occurs in a parallel thread, and the main thread simply throws things into a shared channel (probably a fixed-size channel). There is no reason for dep-graph construction to be on the main thread. (Maybe as a separate PR.)

Regarding performance: adding this tracking does add some overhead, approximately 2% in my measurements (I was comparing the build times for rustdoc). Interestingly, enabling or disabling tracking doesn't seem to do very much. I want to poke at this some more and gather a bit more data -- in some tests I've seen that 2% go away, but on others it comes back. It's not entirely clear to me if that 2% is truly due to constructing the dep-graph at all.

The next big step after this is write some code to dump the dep-graph to disk and reload it.

r? @michaelwoerister
2016-01-06 18:37:57 +00:00
Simonas Kazlauskas
f9814242dc panic/panic_bounds_check to destructure tys
Not any more beautiful.
2016-01-06 13:57:52 +02:00
Simonas Kazlauskas
d1c644c1e9 Merge Call and DivergingCall diffs into CallKind
This merges two separate Call terminators and uses a separate CallKind sub-enum instead.

A little bit unrelatedly, copying into destination value for a certain kind of invoke, is also
implemented here. See the associated comment in code for various details that arise with this
implementation.
2016-01-06 13:57:52 +02:00
Simonas Kazlauskas
cef6aee369 Don’t generate landing-pads if -Z no-landing-pads 2016-01-06 13:57:52 +02:00
Simonas Kazlauskas
4e86dcdb72 Remove diverge terminator
Unreachable terminator can be contained all within the trans.
2016-01-06 13:57:51 +02:00
Simonas Kazlauskas
5b34690842 Remove the Panic block terminator 2016-01-06 13:57:51 +02:00
Simonas Kazlauskas
ecf4d0e3ad Add Resume Terminator which corresponds to resume
Diverge should eventually go away
2016-01-06 13:57:51 +02:00
Simonas Kazlauskas
6f18b559df Generate DivergingCall terminator
This simplifies CFG greatly for some cases :)
2016-01-06 13:57:47 +02:00
Simonas Kazlauskas
893a66d7a1 Split Call into Call and DivergingCall
DivergingCall is different enough from the regular converging Call to warrant the split. This also
inlines CallData struct and creates a new CallTargets enum in order to have a way to differentiate
between calls that do not have an associated cleanup block.

Note, that this patch still does not produce DivergingCall terminator anywhere. Look for that in
the next patches.
2016-01-06 13:40:57 +02:00
bors
7312e0a163 Auto merge of #30692 - michaelwoerister:mir-overloaded-fn-calls, r=nikomatsakis
So far, calls going through `Fn::call`, `FnMut::call_mut`, or `FnOnce::call_once` have not been translated properly into MIR:
The call `f(a, b, c)` where `f: Fn(T1, T2, T3)` would end up in MIR as:
```
call `f` with arguments  `a`, `b`, `c`
```
What we really want is:
```
call `Fn::call` with arguments  `f`, `a`, `b`, `c`
```
This PR transforms these kinds of overloaded calls during `HIR -> HAIR` translation.

What's still a bit funky is that the `Fn` traits expect arguments to be tupled but due to special handling type-checking and trans, we do not actually tuple arguments and everything still checks out fine. So, after this PR we end up with MIR containing calls where function signature and arguments seemingly don't match:
```
call Fn::call(&self, args: (T1, T2, T3)) with arguments `f`, `a`, `b`, `c`
```
instead of
```
call Fn::call(&self, args: (T1, T2, T3)) with arguments `f`, (`a`, `b`, `c`)  //  <- args tupled!
```
It would be nice if the call traits could go without special handling in MIR and later on.
2016-01-06 09:00:57 +00:00
Niko Matsakis
005fa14358 Annotate the compiler with information about what it is doing when. 2016-01-05 21:05:50 -05:00
bors
dc1f442634 Auto merge of #30492 - wesleywiser:fix_extra_drops, r=pnkfelix
Fixes #28159
2016-01-06 01:55:45 +00:00
Michael Woerister
04b6c4939b [MIR] Handle overloaded call expressions during HIR -> HAIR translation. 2016-01-05 12:40:35 -05:00