bors [Wed, 6 Jan 2016 18:37:57 +0000 (18:37 +0000)]
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.
bors [Wed, 6 Jan 2016 13:11:18 +0000 (13:11 +0000)]
Auto merge of #30481 - nagisa:mir-calls-2, r=nikomatsakis
r? @nikomatsakis
This is a pretty big PR conflating changes to a few different block terminators (Call, DivergingCall, Panic, Resume, Diverge), because they are somewhat closely related.
Each commit has a pretty good description on what is being changed in each commit. The end result is greatly simplified CFG and translation for calls (no success branch if the function is diverging, no cleanup branch if there’s nothing to cleanup etc).
This considerably simplifies code around calling functions and translation of Resume itself. This
removes requirement that a block containing Resume terminator is always translated after something
which creates a landing pad, thus allowing us to actually translate some valid MIRs we could not
translate before.
However, an assumption is added that translator is correct (in regards to landing pad generation)
and code will never reach the Resume terminator without going through a landing pad first. Breaking
these assumptions would pass an `undef` value into the personality functions.
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.
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.
bors [Wed, 6 Jan 2016 09:00:57 +0000 (09:00 +0000)]
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.
Niko Matsakis [Tue, 22 Dec 2015 22:17:57 +0000 (17:17 -0500)]
Refactor overlap checker so that it walks the HIR instead of poking into
random tables. The old code was weird anyway because it would
potentially walk traits from other crates etc. The new code fits
seamlessly with the dependency tracking.
bors [Tue, 5 Jan 2016 03:32:12 +0000 (03:32 +0000)]
Auto merge of #30595 - steveklabnik:remove_learn_rust, r=gankro
Some history:
While getting Rust to 1.0, it was a struggle to keep the book in a
working state. I had always wanted a certain kind of TOC, but couldn't
quite get it there.
At the 11th hour, I wrote up "Rust inside other langauges" and "Dining
Philosophers" in an attempt to get the book in the direction I wanted to
go. They were fine, but not my best work. I wanted to further expand
this section, but it's just never going to end up happening. We're doing
the second draft of the book now, and these sections are basically gone
already.
Here's the issues with these two sections, and removing them just fixes
it all:
// Philosophers
There was always controversy over which ones were chosen, and why. This
is kind of a perpetual bikeshed, but it comes up every once in a while.
The implementation was originally supposed to show off channels, but
never did, due to time constraints. Months later, I still haven't
re-written it to use them.
People get different results and assume that means they're wrong, rather
than the non-determinism inherent in concurrency. Platform differences
aggrivate this, as does the exact amount of sleeping and printing.
// Rust Inside Other Languages
This section is wonderful, and shows off a strength of Rust. However,
it's not clear what qualifies a language to be in this section. And I'm
not sure how tracking a ton of other languages is gonna work, into the
future; we can't test _anything_ in this section, so it's prone to
bitrot.
By removing this section, and making the Guessing Game an initial
tutorial, we will move this version of the book closer to the future
version, and just eliminate all of these questions.
In addition, this also solves the 'split-brained'-ness of having two
paths, which has endlessly confused people in the past.
I'm sad to see these sections go, but I think it's for the best.
bors [Tue, 5 Jan 2016 01:43:07 +0000 (01:43 +0000)]
Auto merge of #30707 - tsion:mir-text, r=nikomatsakis
r? @nikomatsakis
Textual MIR can be dumped for a particular `fn` with `#![rustc_mir(pretty = "filename.mir")]`. Below is an example of the text output.
```rust
struct Point {
x: i32,
y: i32,
}
fn example() -> Point {
let mut e = Point { x: 1, y: 2 };
let num = 5;
let plus_num = |x: i32| x + num;
e.y = plus_num(e.x);
e
}
```
```rust
fn() -> Point {
let mut var0: Point; // e
let var1: i32; // num
let var2: [closure@test.rs:84:20: 84:36 num:&i32]; // plus_num
let mut tmp0: ();
let mut tmp1: &i32;
let mut tmp2: ();
let mut tmp3: i32;
let mut tmp4: &[closure@test.rs:84:20: 84:36 num:&i32];
let mut tmp5: i32;
let mut tmp6: Point;
bors [Mon, 4 Jan 2016 22:09:52 +0000 (22:09 +0000)]
Auto merge of #30661 - michaelwoerister:trans_fn_attrs, r=nrc
So far `librustc::trans::base::trans_fn()` and `trans_closure()` have been passed the list of attributes on the function being translated *only* if the function was local and non-generic. For generic functions, functions inlined from other crates, functions with foreign ABI and for closures, only an empty list of attributes was ever passed to `trans_fn()`.
This led to the case that generic functions marked with `#[rustc_mir]` where not actually translated via MIR but via the legacy translation path.
This PR makes function/closure attributes always be passed to `trans_fn()` and disables the one test where this makes a difference.
If there is an actual reason why attributes were not passed along in these cases, let me know.
cc @rust-lang/compiler
cc @luqmana regarding the test case
bors [Mon, 4 Jan 2016 20:24:35 +0000 (20:24 +0000)]
Auto merge of #30602 - tsion:mir-graphviz-display, r=nikomatsakis
r? @nikomatsakis
cc @eddyb @nagisa
This PR changes most of the MIR graphviz debug output, making it smaller and more consistent. Also, it changes all fonts to monospace and adds a graph label containing the type of the `fn` the MIR is for and all the values (arguments, named bindings, and compiler temporaries).
I chose to re-write the graphviz output code instead of using the existing libgraphviz API because I found it much easier to prototype usage of various graphviz features when I had full control of the text output. It also makes the code simpler, I think.
Below are a bunch of example functions and links to their output images on the current nightly vs. this PR. File names starting with numbers (e.g. `80-factorial_fold-new.png`) are for closures. There's still a bunch of low hanging fruit to make it even better, particularly around aggregates and references.
I also imagine the textual output for MIR will be able to closely match the graphviz output. The list of statements should look identical and the terminators will be the same except that the text form will have a list of target blocks (potentially using the same edge labels as the graphviz does). I can PR a simple text output right after this PR.
This is my first large change to the compiler, so if anything should be reorganized/renamed/etc, let me know! Also, feel free to bikeshed the details of the output, though any minor changes can come in future PRs.
bors [Mon, 4 Jan 2016 18:37:21 +0000 (18:37 +0000)]
Auto merge of #30523 - ubsan:wrapping_op_assign, r=eddyb
Add OpAssign to Wrapping<T>, plus fix some problems in core::num::wrapping
including, but not limited to:
* Testing Wrapping<T>
* Pull out a lot of broken code that doesn't need to be there with the new stage0 compiler
* Adding Rem and RemAssign to Wrapping<T>
* Removed 3 (assumed accidental) re-exports, which is a minor [breaking-change].
* Change shl and shr to take all integer types, instead of a usize; this is a more major [breaking-change], because of values that were inferred before, but brings us in line with the integer shifts.
bors [Mon, 4 Jan 2016 16:54:11 +0000 (16:54 +0000)]
Auto merge of #30553 - luqmana:mir-match-arm-guards, r=nikomatsakis
Fixes #30527.
```Rust
fn main() {
let _abc = match Some(101i8) {
Some(xyz) if xyz > 100 => xyz,
Some(_) => -1,
None => -2
};
}
```
Resulting MIR now includes the `Some(xyz)` arm, guard and all:
![match.dot](https://cloud.githubusercontent.com/assets/287063/11999413/066f7610-aa8b-11e5-927b-24215af57fc4.png)
~~Not quite sure how to write a test for this.~~ Thinking too hard, just tested the end result.
bors [Mon, 4 Jan 2016 14:09:15 +0000 (14:09 +0000)]
Auto merge of #30690 - LawrenceWoodman:patch-2, r=steveklabnik
`fs::File` was being referenced without either calling via `std::fs::File` or by using `File` after having used `std::fs::File`. Also `Path` was being referenced without first having used `std::path::Path`.
fs::File was being referenced without either calling via std::fs::File or by using File after having used fs::File. Also Path was being referenced without first having used std::path::Path.
bors [Mon, 4 Jan 2016 03:07:59 +0000 (03:07 +0000)]
Auto merge of #30651 - nagisa:mir-fix-equality-checks, r=eddyb
This is not a fix to checks themselves per se (though we still use `Eq` MIR test instead of calling `PartialEq::eq`), but rather how we handle items we encounter in pattern position.
Previously we would just call `PartialEq` with the constant and the matchee, but now we essentially inline the constant instead. E.g. these two snippets are functionally equivalent at MIR level:
```
match val { Some(42) => true, _ => false }
```
and
```
const SECRET: Option<u8> = Some(42);
match val { SECRET => true, _ => false }
```
This approach also allows for more optimizations of matches. I.e. It can now exploit `SwitchInt` to switch on number inside a `Some` regardless of whether the value being an item or not.
This is based on @tsion’s already approved PR so I could reuse the file for more tests.
bors [Sun, 3 Jan 2016 21:00:46 +0000 (21:00 +0000)]
Auto merge of #30677 - diwic:master, r=bluss
Obviously we can't remove the character one past the end of the String. And we can't today either - we'll just panic at char_at() instead - but if we're going to keep that assertion, we should at least have a correct assertion.
diwic [Sat, 2 Jan 2016 21:36:50 +0000 (22:36 +0100)]
Fix off-by-one in String::remove
Obviously we can't remove the character one past the end of the String. And we can't today either - we'll just panic at char_at() instead - but if we're going to keep that assertion, we should at least have a correct assertion.
bors [Fri, 1 Jan 2016 16:38:40 +0000 (16:38 +0000)]
Auto merge of #30670 - emoon:fs-copy-comment, r=steveklabnik
When looking in the documentation I often scan the examples the first thing I do. In these 3 cases it's not obvious which direction the operation happens by adding this comment it makes it more obvious.
bors [Thu, 31 Dec 2015 20:52:17 +0000 (20:52 +0000)]
Auto merge of #30616 - arcnmx:cstr-asref, r=aturon
Are trait impls still insta-stable? Considering that this design has been around for a long time on `String` and `OsString` it probably doesn't matter much...
The `From` impl is a bit strange to me. It's stolen from `OsString` but I'm not really sure about it... `String` just impls `From<&str>` instead, would that make more sense?
Rollup merge of #30630 - tsion:mir-closure-args, r=nagisa
Previously, all references to closure arguments went to the argument before the one they should (e.g. to `arg1` when it was supposed to go to `arg2`). This was because the MIR builder did not account for the implicit arguments that come before the explicit arguments, and closures have one implicit argument - the struct containing the captures.
This is my test code and a diff of the MIR generated for the closure:
```rust
let a = 2i32;
let _f = |b: i32| -> i32 { a + b }:
```
```diff
--- old 2015-12-29 23:16:32.027926372 -0600
+++ new 2015-12-29 23:16:42.975400757 -0600
@@ -1,22 +1,22 @@
fn(arg0: &[closure@closure-args.rs:8:14: 8:39 a:&i32], arg1: i32) -> i32 {
let var0: i32; // b
let tmp0: ();
let tmp1: i32;
let tmp2: i32;
(If you're wondering where this text MIR output comes from, it's from another branch of mine waiting on https://github.com/rust-lang/rust/pull/30602 to get merged.)
Rollup merge of #30590 - nagisa:mir-constval-function, r=luqmana
This moves back (essentially reverts #30265) into MIR-specific translation code, but keeps the
funcition split out, since it is expected to eventually become recursive.