Commit Graph

8404 Commits

Author SHA1 Message Date
Niko Matsakis
259379426c Revamp the "future incompatible" section to clarify the situation
better
2016-01-12 12:53:55 -05:00
Simonas Kazlauskas
19820c4488 Rollup merge of #30768 - steveklabnik:gh28953, r=alexcrichton
Fixes #28953
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
Simonas Kazlauskas
caf6095fcf Rollup merge of #30737 - Ms2ger:MutateMode, r=sanxiyn 2016-01-11 21:17:52 +02:00
bors
d01ed8ad8e Auto merge of #30676 - nikomatsakis:issue-29857, r=arielb1
This is an alternative to https://github.com/rust-lang/rust/pull/29954 for fixing #29857 that seems to me to be more inline with the general strategy around `TyError`. It also includes the fix for #30589 -- in fact, just the minimal change of making `ty_is_local` tolerate `TyError` avoids the ICE, but you get a lot of duplicate error reports, so in the case where the impl's trait reference already includes `TyError`, we just ignore the impl altogether.

cc @arielb1 @sanxiyn

Fixes #29857.
Fixes #30589.
2016-01-11 15:26:57 +00:00
bors
5cf69aa951 Auto merge of #30753 - pnkfelix:downgrade-29383-struct-warnings-to-errors, r=nikomatsakis
Downgrade unit struct match via S(..) warnings to errors

The error signalling was introduced in #29383

It was noted as a warning-cycle-less regression in #30379

Fix #30379
2016-01-11 13:39:06 +00:00
Niko Matsakis
77756cb12a Change error scheme so that if projection fails we generate A::B instead of TyError 2016-01-08 20:20:02 -05:00
Niko Matsakis
64b720229c Remove ErrorCandidate in favor of just generating an ambiguous result 2016-01-08 20:20:02 -05:00
Niko Matsakis
b4f5ddba67 Make coherence more tolerant of error types.
Fixes #29857.
Fixes #30589.
2016-01-08 20:20:01 -05: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
Felix S. Klock II
40e2ac28e4 Added proper lint for the unit variant/struct warning. 2016-01-08 02:07:28 +01:00
bors
64a8ffeffa Auto merge of #30757 - michaelwoerister:mir-visitor-cleanup, r=jroesch
After a call to `visit_def_id()` missing in `mir::visit::Visitor` but not `mir::visit::MutVisitor` has caused me a couple hours of error hunting, I decided I'd take the time to get rid of the code duplication between the two implementations.

cc @rust-lang/compiler
2016-01-07 22:54:22 +00:00
bors
5c92010d3b Auto merge of #30748 - tsion:mir-tuple-fix, r=eddyb
r? @nikomatsakis

(Related issue about `debug_tuple` at https://github.com/rust-lang/rfcs/issues/1448.)

```rust

fn main() {
    let _x = ();
}
```

```diff
--- empty_tuple-old.mir	2016-01-06 16:04:24.206409186 -0600
+++ empty_tuple-new.mir	2016-01-06 14:26:17.324888585 -0600
@@ -1,13 +1,13 @@
 fn() -> () {
     let var0: (); // _x
     let mut tmp0: ();

     bb0: {
-        var0 = ;
+        var0 = ();
         Some(goto -> bb1);
     }

     bb1: {
         Some(return);
     }
 }
```
2016-01-07 21:04:36 +00:00
Steve Klabnik
ce49e3225e Expand EO308 to mention try!
Fixes #28953
2016-01-07 14:09:20 -05:00
bors
03f4950239 Auto merge of #30734 - tsion:mir-pretty, r=nikomatsakis
* Put `const` in front of every `ConstVal`.
* Pretty-print bytestrings as they appear in Rust source.
* Pretty-print `ConstVal::{Struct, Tuple, Array, Repeat}` by pretty-printing the `ast::NodeId`. This is a temporary measure, and probably not perfect, but I'm avoiding anything more complex since I hear the const evaluator might not be AST-based in the near future.

```rust

struct Point {
    x: i32,
    y: i32,
}

fn consts() {
    let _float = 3.14159;
    let _non_const_int = -42;
    const INT: i32 = -42;
    let _int = INT;
    let _uint = 42u32;
    let _str = "a string";
    let _bytestr = b"a bytes\xFF\n\ttri\'\"\\ng";
    let _bool = true;
    const STRUCT: Point = Point { x: 42, y: 42 };
    let _struct = STRUCT;
    const EXTERNAL_STRUCT: std::sync::atomic::AtomicUsize = std::sync::atomic::ATOMIC_USIZE_INIT;
    let _external_struct = EXTERNAL_STRUCT;
    const TUPLE: (i32, &'static str, &'static [u8; 5]) = (1, "two", b"three");
    let _tuple = TUPLE;
    const FUNC: fn() = consts;
    let _function = FUNC;
    let _non_const_function = consts;
    const ARRAY: [&'static str; 3] = ["a", "b", "c"];
    let _array = ARRAY;
    const REPEAT: [&'static [u8; 3]; 10] = [b"foo"; 10];
    let _repeat = REPEAT;
}
```

```diff
--- consts-old.mir	2016-01-05 23:23:14.163807017 -0600
+++ consts-new.mir	2016-01-05 23:04:51.121386151 -0600
@@ -1,45 +1,45 @@
 fn() -> () {
     let var0: f64; // _float
     let var1: i32; // _non_const_int
     let var2: i32; // _int
     let var3: u32; // _uint
     let var4: &str; // _str
     let var5: &[u8; 18]; // _bytestr
     let var6: bool; // _bool
     let var7: Point; // _struct
     let var8: core::sync::atomic::AtomicUsize; // _external_struct
     let var9: (i32, &str, &[u8; 5]); // _tuple
     let var10: fn(); // _function
     let var11: fn() {consts}; // _non_const_function
     let var12: [&str; 3]; // _array
     let var13: [&[u8; 3]; 10]; // _repeat
     let mut tmp0: ();

     bb0: {
-        var0 = 3.14159;
-        var1 = Neg(42);
-        var2 = -42;
-        var3 = 42;
-        var4 = Str("a string");
-        var5 = ByteStr[97, 32, 98, 121, 116, 101, 115, 255, 10, 9, 116, 114, 105, 39, 34, 92, 110, 103];
-        var6 = true;
-        var7 = Struct(51);
+        var0 = const 3.14159;
+        var1 = Neg(const 42);
+        var2 = const -42;
+        var3 = const 42;
+        var4 = const "a string";
+        var5 = const b"a bytes\xff\n\ttri\'\"\\ng";
+        var6 = const true;
+        var7 = const expr Point{x: 42, y: 42,};
         var8 = consts::EXTERNAL_STRUCT;
-        var9 = Tuple(78);
-        var10 = Function(DefId { krate: 0, node: DefIndex(7) => consts });
+        var9 = const expr (1, "two", b"three");
+        var10 = const consts;
         var11 = consts;
-        var12 = Array(105, 3);
-        var13 = Repeat(122, 10);
+        var12 = const expr ["a", "b", "c"];
+        var13 = const expr [b"foo"; 10];
         drop var8;
         drop var7;
         goto -> bb1;
     }

     bb1: {
         return;
     }

     bb2: {
         diverge;
     }
 }
```
2016-01-07 14:22:49 +00:00
bors
1e8350387c Auto merge of #30317 - jseyfried:refactor_type_folder, r=nikomatsakis
`TypeFoldable`s can currently be visited inefficiently with an identity folder that is run only for its side effects. This creates a more efficient visitor for `TypeFoldable`s and uses it to implement `RegionEscape` and `HasProjectionTypes`, fixing cleanup issue #20298.
This is a pure refactoring.
2016-01-07 11:48:35 +00:00
Michael Woerister
8f51188a8e Factor mir::[Mut]Visitor implementations into a common macro. 2016-01-07 05:49:46 -05:00
bors
91b27ec9be Auto merge of #30724 - nikomatsakis:feature-gate-defaulted-type-parameters, r=pnkfelix
It was recently realized that we accept defaulted type parameters everywhere, without feature gate, even though the only place that we really *intended* to accept them were on types. This PR adds a lint warning unless the "type-parameter-defaults" feature is enabled. This should eventually become a hard error.

This is a [breaking-change] in that new feature gates are required (or simply removing the defaults, which is probably a better choice as they have little effect at this time). Results of a [crater run][crater] suggest that approximately 5-15 crates are affected. I didn't do the measurement quite right so that run cannot distinguish "true" regressions from "non-root" regressions, but even the upper bound of 15 affected crates seems relatively minimal.

[crater]: https://gist.github.com/nikomatsakis/760c6a67698bd24253bf

cc @rust-lang/lang
r? @pnkfelix
2016-01-07 06:32:56 +00:00
Jeffrey Seyfried
6327563963 Rename fold_subitems_with to super_fold_with 2016-01-07 00:42:30 +00:00
Jeffrey Seyfried
76021d84b3 Refactor away extension traits RegionEscape and HasTypeFlags 2016-01-07 00:42:12 +00:00
Jeffrey Seyfried
f9808ea4b4 Create a visitor for TypeFoldables and use it to implement RegionEscape and HasTypeFlags (fixes #20298) 2016-01-07 00:40:18 +00:00
Scott Olson
b7fa37d03e Fix pretty-printing for empty tuples in MIR. 2016-01-06 14:17:38 -06: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
Niko Matsakis
0c8ee65020 Use memoized helper more often. 2016-01-06 10:16:58 -05:00
Niko Matsakis
a9d7e36668 Fix numerous typos, renamings, and minor nits raised by mw. 2016-01-06 09:19:19 -05:00
Ms2ger
6f0e58fc5f Stop re-exporting MutateMode's variants. 2016-01-06 13:16:30 +01: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
a1e13983f7 Have a cached unreachable block inside MIR state
It is useful for various cases where direct unreachable cannot be translated and a separate block
is necessary.
2016-01-06 13:57:51 +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
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
Scott Olson
b2903d87c9 Improve pretty-printing for ConstVals in MIR. 2016-01-05 23:08:16 -06:00
Niko Matsakis
11c671b59c Workaround stage0 bug 2016-01-05 21:05:51 -05:00
Niko Matsakis
d48f48f61f Refactor compiler to make use of dep-tracking-maps. Also, in cases where
we were using interior mutability (RefCells, TyIvar), add some reads/writes.
2016-01-05 21:05:51 -05:00
Niko Matsakis
005fa14358 Annotate the compiler with information about what it is doing when. 2016-01-05 21:05:50 -05:00
Niko Matsakis
aa265869ba Add DepGraph to tcx. 2016-01-05 21:05:50 -05:00
Niko Matsakis
c77cd480cf Introduce the DepGraph and DepTracking map abstractions,
along with a README explaining how they are to be used
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
Scott Olson
c785802c0a Boring whitespace cleanup. 2016-01-05 17:26:22 -06:00
Niko Matsakis
6dd3f6143e convert from hard error to future-incompatible lint 2016-01-05 16:21:53 -05:00
Niko Matsakis
27d6b9d215 improve visibility of future-incompatibilities (mildly, at least) 2016-01-05 16:21:53 -05:00
Scott Olson
c9a7171e10 Pretty-print ReturnPointer as 'return' in MIR. 2016-01-04 16:11:33 -06:00
Scott Olson
19a50e4f2a Pretty-print static lvalues in MIR as just their path. 2016-01-04 16:11:33 -06:00
Scott Olson
6a33221ea5 Improve pretty-printing of references in MIR. 2016-01-04 16:11:33 -06:00
Scott Olson
522354415e Pretty-print aggregates more prettily in MIR. 2016-01-04 16:11:32 -06:00
Scott Olson
9db76f311d Use fmt::Result instead of Result<(), Error>. 2016-01-04 16:11:32 -06:00
Scott Olson
5a0c1b3a88 Print BasicBlock names in lowercase. 2016-01-04 16:11:32 -06:00
bors
badc23b6ad 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.

```rust
fn empty() {}
```

http://vps.solson.me/mir-graphviz/empty-new.png
http://vps.solson.me/mir-graphviz/empty-old.png

```rust
fn constant() -> i32 {
    42
}
```

http://vps.solson.me/mir-graphviz/constant-new.png
http://vps.solson.me/mir-graphviz/constant-old.png

```rust
fn increment(x: i32) -> i32 {
    x + 1
}
```

http://vps.solson.me/mir-graphviz/increment-new.png
http://vps.solson.me/mir-graphviz/increment-old.png

```rust
fn factorial_recursive(n: usize) -> usize {
    if n == 0 {
        1
    } else {
        n * factorial_recursive(n - 1)
    }
}
```

http://vps.solson.me/mir-graphviz/factorial_recursive-new.png
http://vps.solson.me/mir-graphviz/factorial_recursive-old.png

```rust
fn factorial_iterative(n: usize) -> usize {
    let mut prod = 1;
    for x in 1..n {
        prod *= x;
    }
    prod
}
```

http://vps.solson.me/mir-graphviz/factorial_iterative-new.png
http://vps.solson.me/mir-graphviz/factorial_iterative-old.png

```rust
fn factorial_fold(n: usize) -> usize {
    (1..n).fold(1, |prod, x| prod * x)
}
```

http://vps.solson.me/mir-graphviz/factorial_fold-new.png
http://vps.solson.me/mir-graphviz/factorial_fold-old.png
http://vps.solson.me/mir-graphviz/80-factorial_fold-new.png
http://vps.solson.me/mir-graphviz/80-factorial_fold-old.png

```rust
fn collatz(mut n: usize) {
    while n != 1 {
        if n % 2 == 0 {
            n /= 2;
        } else {
            n = 3 * n + 1;
        }
    }
}
```

http://vps.solson.me/mir-graphviz/collatz-new.png
http://vps.solson.me/mir-graphviz/collatz-old.png

```rust
fn multi_switch(n: usize) -> usize {
    match n {
        5 | 10 | 15 => 3,
        20 | 30 => 2,
        _ => 1,
    }
}
```

http://vps.solson.me/mir-graphviz/multi_switch-new.png
http://vps.solson.me/mir-graphviz/multi_switch-old.png
2016-01-04 20:24:35 +00:00