Commit Graph

49163 Commits

Author SHA1 Message Date
Simonas Kazlauskas
50107034c0 Add tests 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
20ec53a0d3 Fix ReturnPointer generation for void return types
Fixes #30480
2016-01-06 13:57:52 +02:00
Simonas Kazlauskas
924bb1e5eb Refine call terminator translation
* Implement landing pads; and
* Implement DivergingCall translation; and
* Modernise previous implementation of Call somewhat.
2016-01-06 13:57:51 +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
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
bors
dc1f442634 Auto merge of #30492 - wesleywiser:fix_extra_drops, r=pnkfelix
Fixes #28159
2016-01-06 01:55:45 +00:00
Michael Woerister
e281509dce [MIR] Add test case for translation of closure calls. 2016-01-05 12:50:54 -05:00
Michael Woerister
7d357190ff [MIR] Implement calling of closures and add missing monomorphization when translating function references. 2016-01-05 12:50:46 -05:00
Michael Woerister
04b6c4939b [MIR] Handle overloaded call expressions during HIR -> HAIR translation. 2016-01-05 12:40:35 -05:00
bors
bd58fd8438 Auto merge of #30665 - zachpanz88:new-year, r=nrc
New copyright date

Happy new year!
2016-01-05 13:54:30 +00:00
bors
5253294d22 Auto merge of #30702 - tshepang:derives-not-needed, r=steveklabnik
Also sneak in a missing trailing comma
2016-01-05 10:24:37 +00:00
bors
3a6c6c8e01 Auto merge of #30680 - wesleywiser:rustdoc_image_max_width, r=steveklabnik
Fixes #24861
2016-01-05 08:37:06 +00:00
bors
dbacacda8a Auto merge of #30708 - GuillaumeGomez:malformed_macro, r=sanxiyn
Part of #30669
2016-01-05 05:20:27 +00:00
bors
803c3e2ee8 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.

Fixes #30471
Fixes #30163
Fixes #30162
Fixes #25488
Fixes #30345
Fixes #29590
Fixes #28713
Fixes #28915

And probably others. This lengthy list alone is enough to show that
these should have been removed.

RIP.
2016-01-05 03:32:12 +00:00
bors
e2d649405a 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;

    bb0: {
        var0 = Point { x: 1, y: 2 };
        var1 = 5;
        tmp1 = &var1;
        var2 = [closure@test.rs:84:20: 84:36] { num: tmp1 };
        tmp4 = &var2;
        tmp5 = var0.0;
        tmp3 = tmp4(tmp5) -> [return: bb3, unwind: bb4];
    }

    bb1: {
        return;
    }

    bb2: {
        diverge;
    }

    bb3: {
        drop var0.1;
        var0.1 = tmp3;
        drop tmp2;
        drop var2;
        drop var0;
        tmp6 = var0;
        return = tmp6;
        drop tmp6;
        goto -> bb1;
    }

    bb4: {
        drop var2;
        goto -> bb5;
    }

    bb5: {
        drop var0;
        goto -> bb2;
    }
}
```

```rust
fn(arg0: &[closure@test.rs:84:20: 84:36 num:&i32], arg1: i32) -> i32 {
    let var0: i32; // x
    let mut tmp0: ();
    let mut tmp1: i32;
    let mut tmp2: i32;

    bb0: {
        var0 = arg1;
        tmp1 = var0;
        tmp2 = (*(*arg0).0);
        return = Add(tmp1, tmp2);
        goto -> bb1;
    }

    bb1: {
        return;
    }

    bb2: {
        diverge;
    }
}
```
2016-01-05 01:43:07 +00:00
bors
d5e229057c Auto merge of #30681 - Toby-S:master, r=bluss
Make `".".parse::<f32>()` and `".".parse::<f64>()` return Err

This fixes #30344.

This is a [breaking-change], which the libs team have classified as a
bug fix.
2016-01-04 23:57:46 +00:00
Scott Olson
080994a189 Add 'mut' to MIR temp variable debug output. 2016-01-04 16:11:33 -06: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
Scott Olson
661976cbd1 Add a human-readable textual form for MIR.
This can be dumped for a particular `fn` with the attribute
`#![rustc_mir(pretty = "filename.mir"]`.
2016-01-04 16:11:32 -06:00
bors
41611baece 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
2016-01-04 22:09:52 +00:00
Tshepang Lekhonkhobe
ae96ce33e7 doc: these examples do not need Copy and Clone traits
Also sneak in a missing trailing comma
2016-01-04 22:38:27 +02: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
bors
5e8cb3819b 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.

Fixes #30524 and #30523
2016-01-04 18:37:21 +00:00
Toby Scrace
33f3c52d32 Make float parsing "." return Err
This makes both of the following return Err:

    ".".parse::<f32>()
    ".".parse::<f64>()

This is a [breaking-change], which the libs team have classified as a
bug fix.
2016-01-04 18:23:33 +00:00
bors
b62289153c 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.

r? @nikomatsakis
2016-01-04 16:54:11 +00:00
bors
543bb03d3e 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`.
2016-01-04 14:09:15 +00:00
Lawrence Woodman
0c3d6b46ac Add missing use statements
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.
2016-01-04 07:21:48 +00:00
bors
191ff2d8fd 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.

r? @eddyb
cc @nikomatsakis @tsion
2016-01-04 03:07:59 +00:00
bors
99e59dec5a Auto merge of #29732 - nathansizemore:master, r=steveklabnik 2016-01-04 00:27:40 +00:00
Guillaume Gomez
6e68cdfcc2 Add test for "malformed macro lhs" and change back span_bug to span_fatal 2016-01-04 01:13:57 +01:00
bors
8f11a9ef4e 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.
2016-01-03 21:00:46 +00:00
bors
cae9267d47 Auto merge of #29949 - fhahn:issue-21659-show-relevant-trait-impls, r=arielb1
This PR for #21659 uses `DefId.for_each_relevant_impl()` to show other possible implementations in the "trait not implemented" message.
2016-01-03 19:14:20 +00:00
Wesley Wiser
4dee31c119 Rustdoc - Specify max-image size
Fixes #24861
2016-01-02 21:38:36 -05:00
Nicholas Mazzuca
402259da38 Take out Op<T>/OpAssign<T> for Wrapping<T> 2016-01-02 15:34:55 -08:00
Florian Hahn
a8d60708ec Refactor candidate selection 2016-01-03 00:11:48 +01:00
Nicholas Mazzuca
cd3aa31e6d Finish test implementation 2016-01-02 14:36:28 -08:00
diwic
8b398ed823 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.
2016-01-02 22:36:50 +01:00
Florian Hahn
25e4389866 Use for_each_impl 2016-01-02 19:47:41 +01:00
Florian Hahn
ba24fbd404 Manually check trait implementations 2016-01-02 19:47:02 +01:00