Commit Graph

444 Commits

Author SHA1 Message Date
Eduard Burtescu
e5a91b7ba1 mir: don't attempt to promote Unpromotable constant temps. 2016-05-10 21:26:34 +03:00
Eduard Burtescu
ed66fe48e9 Implement RFC 1440 "Allow Drop types in statics/const functions". 2016-05-07 19:14:33 +03:00
Eduard Burtescu
78884b7659 mir: qualify and promote constants. 2016-05-07 19:14:28 +03:00
Eduard Burtescu
14efbf1481 mir: prepare for rvalue promotion support. 2016-05-07 07:19:10 +03:00
Eduard Burtescu
d434688516 mir: build MIR for constants and static initializers. 2016-05-07 07:15:01 +03:00
Eduard Burtescu
cde2f5f116 mir: factor out the parts of MIR building which are not fn-specific. 2016-05-07 07:14:54 +03:00
Eduard Burtescu
bbc41aa9a6 mir: remove the unused attribute logic in the MIR map construction. 2016-05-07 06:43:57 +03:00
bors
c95cda56a6 Auto merge of #33267 - nagisa:mir-temporary-32959, r=nikomatsakis
[MIR] Temporary hack for 32959

Gets rid of the warning. This is more elegant that I thought it would be, actually.

r? @nikomatsakis

cc #32959
2016-05-06 18:15:39 -07:00
James Miller
3906aef5c6 Handle coercion casts properly when building the MIR
Coercion casts (`expr as T` where the type of `expr` can be coerced to
`T`) are essentially no-ops, as the actual work is done by a coercion.
Previously a check for type equality was used to avoid emitting the
redundant cast in the MIR, but this failed for coercion casts of
function items that had lifetime parameters. The MIR trans code doesn't
handle `FnPtr -> FnPtr` casts and produced an error.

Also fixes a bug with type ascription expressions not having any
adjustments applied.

Fixes #33295
2016-05-01 17:56:07 +12:00
Simonas Kazlauskas
603a833480 Temporary hack for 32959
Gets rid of the warning
2016-04-29 03:16:29 +03:00
James Miller
89edd96be8 Fix translation of Assign/AssignOp as rvalues
In code like `let x = y = z;`, `y = z` goes through `as_rvalue`, which
didn't handle it. Now it translates the assignment and produces `()`
directly.
2016-04-28 13:18:51 +12:00
James Miller
c2de80f05f Address comments
Moves `stmt_expr` into its own module, `expr::stmt`.
2016-04-28 13:18:51 +12:00
James Miller
f242fe3c04 Various improvements to MIR and LLVM IR Construction
Primarily affects the MIR construction, which indirectly improves LLVM
IR generation, but some LLVM IR changes have been made too.

* Handle "statement expressions" more intelligently. These are
  expressions that always evaluate to `()`. Previously a temporary would
  be generated as a destination to translate into, which is unnecessary.

  This affects assignment, augmented assignment, `return`, `break` and
  `continue`.
* Avoid inserting drops for non-drop types in more places. Scheduled
  drops were already skipped for types that we knew wouldn't need
  dropping at construction time. However manually-inserted drops like
  those for `x` in `x = y;` were still generated. `build_drop` now takes
  a type parameter like its `schedule_drop` counterpart and checks to
  see if the type needs dropping.
* Avoid generating an extra temporary for an assignment where the types
  involved don't need dropping. Previously an expression like
  `a = b + 1;` would result in a temporary for `b + 1`. This is so the
  RHS can be evaluated, then the LHS evaluated and dropped and have
  everything work correctly. However, this isn't necessary if the `LHS`
  doesn't need a drop, as we can just overwrite the existing value.
* Improves lvalue analysis to allow treating an `Rvalue::Use` as an
  operand in certain conditions. The reason for it never being an
  operand is so it can be zeroed/drop-filled, but this is only true for
  types that need dropping.

The first two changes result in significantly fewer MIR blocks being
generated, as previously almost every statement would end up generating
a new block due to the drop of the `()` temporary being generated.
2016-04-28 13:17:43 +12:00
Manish Goregaokar
a31658de51
Rollup merge of #33041 - petrochenkov:path, r=nrc,Manishearth
Paths are mostly parsed without taking whitespaces into account, e.g. `std :: vec :: Vec :: new ()` parses successfully, however, there are some special cases involving keywords `super`, `self` and `Self`. For example, `self::` is considered a path start only if there are no spaces between `self` and `::`. These restrictions probably made sense when `self` and friends weren't keywords, but now they are unnecessary.

The first two commits remove this special treatment of whitespaces by removing `token::IdentStyle` entirely and therefore fix https://github.com/rust-lang/rust/issues/14109.
This change also affects naked `self` and `super` (which are not tightly followed by `::`, obviously) they can now be parsed as paths, however they are still not resolved correctly in imports (cc @jseyfried, see `compile-fail/use-keyword.rs`), so https://github.com/rust-lang/rust/issues/29036 is not completely fixed.

The third commit also makes `super`, `self`, `Self` and `static` keywords nominally (before this they acted as keywords for all purposes) and removes most of remaining \"special idents\".

The last commit (before tests) contains some small improvements - some qualified paths with type parameters are parsed correctly, `parse_path` is not used for parsing single identifiers, imports are sanity checked for absence of type parameters - such type parameters can be generated by syntax extensions or by macros when https://github.com/rust-lang/rust/issues/10415 is fixed (~~soon!~~already!).

This patch changes some pretty basic things in `libsyntax`, like `token::Token` and the keyword list, so it's a plugin-[breaking-change].

r? @eddyb
2016-04-25 00:47:44 +05:30
Vadim Petrochenkov
b32d7b5923 syntax: Merge keywords and remaining special idents in one list
Simplify the macro used for generation of keywords
Make `Keyword::ident` private
2016-04-24 20:59:44 +03:00
Niko Matsakis
ecd10f04ce thread tighter span for closures around
Track the span corresponding to the `|...|` part of the closure.
2016-04-24 18:10:57 +05:30
bors
6e03608209 Auto merge of #33030 - nagisa:mir-unrequire-end-block, r=nikomatsakis
MIR: Do not require END_BLOCK to always exist

Basically, all this does, is removing restriction for END_BLOCK to exist past the first invocation of RemoveDeadBlocks pass. This way for functions whose CFG does not reach the `END_BLOCK` end up not containing the block.

As far as the implementation goes, I’m not entirely satisfied with the `BasicBlock::end_block`. I had hoped to make `new` a `const fn` and then just have a `const END_BLOCK` private to mir::build, but it turns out that constant functions don’t yet support conditionals nor a way to assert.
2016-04-20 21:25:26 -07:00
Simonas Kazlauskas
d1180afbd9 Generate block containing return lazily instead 2016-04-20 00:13:30 +03:00
Eduard Burtescu
e2ac9895d6 mir: place match pattern bindings in their respective arms. 2016-04-16 21:51:30 +03:00
Eduard Burtescu
f06bab7758 debuginfo: argument and upvar names for MIR. 2016-04-16 21:51:26 +03:00
Simonas Kazlauskas
135657206f MIR: Do not require END_BLOCK to always exist
Once upon a time, along with START_BLOCK and END_BLOCK in the castle of important blocks also lived
a RESUME_BLOCK (or was it UNWIND_BLOCK? Either works, I don’t remember anymore). This trinity of
important blocks were required to always exist from the birth to death of the MIR-land they
belonged to.

Some time later, it was discovered that RESUME_BLOCK was just a lazy goon enjoying comfortable life
in the light of fame of the other two. Needless to say, once found out, the RESUME_BLOCK was
quickly slain and disposed of.

Now, the all-seeing eye of ours discovers that END_BLOCK is actually the more evil and better
disguised twin of the slain RESUME_BLOCK. Thus END_BLOCK gets slain and quickly disposed
of. Glory to the START_BLOCK, one and only lord of the important blocks’ castle!

---

Basically, all this does, is removing restriction for END_BLOCK to exist past the first invocation
of RemoveDeadBlocks pass. This way for functions whose CFG does not reach the `END_BLOCK` end up
not containing the block.

As far as the implementation goes, I’m not entirely satisfied with the `BasicBlock::end_block`, I
had hoped to make `new` a `const fn` and then just have a `const END_BLOCK` private to mir::build,
but it turns out that constant functions don’t yet support conditionals nor a way to assert.
2016-04-16 18:09:51 +03:00
Steve Klabnik
302f2aa01c Rollup merge of #32932 - Manishearth:fx-mir, r=bluss
Make rustc_mir pass rustdoc

None
2016-04-14 14:49:11 -04:00
Manish Goregaokar
3e93a6e265 Make librustc_mir pass rustdoc --test 2016-04-13 16:16:14 +05:30
Manish Goregaokar
327ce2ecf9 Make librustc_mir pass rustdoc 2016-04-13 16:13:24 +05:30
Eduard Burtescu
f680c623d4 mir: store the span of a scope in the ScopeData. 2016-04-11 20:49:07 +03:00
Eduard Burtescu
a563711b6a mir: print the scope and span for variables. 2016-04-11 20:49:07 +03:00
Niko Matsakis
a9b6205aff break dep-graph into modules, parameterize DepNode
it is useful later to customize how change the type we use for reference
items away from DefId
2016-04-06 12:42:46 -04:00
Eduard Burtescu
e8a8dfb056 rustc: retire hir::map's paths. 2016-04-06 13:51:55 +03:00
Eduard Burtescu
20f0f3c1f1 rustc: move some maps from ty to hir. 2016-04-06 09:14:21 +03:00
Eduard Burtescu
ffca6c3e15 rustc: move middle::{def,def_id,pat_util} to hir. 2016-04-06 09:14:21 +03:00
Eduard Burtescu
ef4c7241f8 rustc: dismantle hir::util, mostly moving functions to methods. 2016-04-06 09:01:55 +03:00
Eduard Burtescu
8b0937293b rustc: move rustc_front to rustc::hir. 2016-04-06 09:01:55 +03:00
Manish Goregaokar
f6019760f9 Rollup merge of #32596 - soltanmm:lazy, r=nikomatsakis
Plumb obligations through librustc/infer

Like #32542, but more like #31867.

TODO before merge: make an issue for the propagation of obligations through... uh, everywhere... then replace the `#????`s with the actual issue number.

cc @jroesch
r? @nikomatsakis
2016-04-05 16:43:21 +05:30
Masood Malekghassemi
86071aca3d Address nits 2016-04-04 12:41:05 -07:00
bors
c0b8c43820 Auto merge of #32210 - Aatch:mir-traversal, r=nikomatsakis
rBreak Critical Edges and other MIR work

This PR is built on top of #32080.

This adds the basic depth-first traversals for MIR, preorder, postorder and reverse postorder. The MIR blocks are now translated using reverse postorder. There is also a transform for breaking critical edges, which includes the edges from `invoke`d calls (`Drop` and `Call`), to account for the fact that we can't add code after an `invoke`. It also stops generating the intermediate block (since the transform essentially does it if necessary already).

The kinds of cases this deals with are difficult to produce, so the test is the one I managed to get. However, it seems to bootstrap with `-Z orbit`, which it didn't before my changes.
2016-04-03 08:58:59 -07:00
James Miller
605bc04264 Use a BitVector instead of Vec<bool> for recording cleanup blocks
Also adds a FromIterator impl for BitVector to allow construction of a
BitVector from an iterator yeilding bools.
2016-04-03 14:58:34 +12:00
Benjamin Herr
8aaf6eee2f librustc_mir: use bug!(), span_bug!() 2016-03-31 22:04:23 +02:00
James Miller
63321ca193 Turn break critical edges into a MIR pass
Also adds a new set of passes to run just before translation that
"prepare" the MIR for codegen. Removal of landing pads, region erasure
and break critical edges are run in this pass.

Also fixes some merge/rebase errors.
2016-03-31 15:13:24 +13:00
Oliver Schneider
3eac64747f move const_eval and check_match out of librustc 2016-03-30 13:43:36 +02:00
Oliver Schneider
6cc449ad24 rename rustc_const_eval to rustc_const_math 2016-03-30 11:10:21 +02:00
Masood Malekghassemi
dcdf3d62c1 Plumb obligations through librustc/infer 2016-03-29 20:06:42 -07:00
James Miller
c70bc3a5da Don't build a map of predecessors, just count them instead 2016-03-30 13:00:02 +13:00
James Miller
eee7f3c732 Add and use a break critical edges transform
This is a fairly standard transform that inserts blocks along critical
edges so code can be inserted along the edge without it affecting other
edges. The main difference is that it considers a Drop or Call
terminator that would require an `invoke` instruction in LLVM a critical
edge. This is because we can't actually insert code after an invoke, so
it ends up looking similar to a critical edge anyway.

The transform is run just before translation right now.
2016-03-30 12:59:57 +13:00
James Miller
60a28e60aa Add some standard traversal iterators for MIR
Adds Preorder, Postorder and Reverse Postorder traversal iterators.

Also makes trans/mir use Reverse Postorder traversal for blocks.
2016-03-30 12:57:43 +13:00
Eduard Burtescu
5efdde0de1 rustc: move cfg, infer, traits and ty from middle to top-level. 2016-03-27 01:05:54 +02:00
Eduard Burtescu
5647586ed3 rustc: move middle::subst into middle::ty. 2016-03-27 01:05:53 +02:00
Manish Goregaokar
317acb7d13 Rollup merge of #32482 - nikomatsakis:erase-via-visitor, r=nagisa
use new visitor to erase regions

r? @nagisa
2016-03-26 13:42:05 +05:30
Manish Goregaokar
128b2ad829 Rollup merge of #32199 - nikomatsakis:limiting-constants-in-patterns-2, r=pnkfelix
Restrict constants in patterns

This implements [RFC 1445](https://github.com/rust-lang/rfcs/blob/master/text/1445-restrict-constants-in-patterns.md). The primary change is to limit the types of constants used in patterns to those that *derive* `Eq` (note that implementing `Eq` is not sufficient). This has two main effects:

1. Floating point constants are linted, and will eventually be disallowed. This is because floating point constants do not implement `Eq` but only `PartialEq`. This check replaces the existing special case code that aimed to detect the use of `NaN`.
2. Structs and enums must derive `Eq` to be usable within a match.

This is a [breaking-change]: if you encounter a problem, you are most likely using a constant in an expression where the type of the constant is some struct that does not currently implement
`Eq`. Something like the following:

```rust
struct SomeType { ... }
const SOME_CONST: SomeType = ...;

match foo {
    SOME_CONST => ...
}
```

The easiest and most future compatible fix is to annotate the type in question with `#[derive(Eq)]` (note that merely *implementing* `Eq` is not enough, it must be *derived*):

```rust
struct SomeType { ... }
const SOME_CONST: SomeType = ...;

match foo {
    SOME_CONST => ...
}
```

Another good option is to rewrite the match arm to use an `if` condition (this is also particularly good for floating point types, which implement `PartialEq` but not `Eq`):

```rust
match foo {
    c if c == SOME_CONST => ...
}
```

Finally, a third alternative is to tag the type with `#[structural_match]`; but this is not recommended, as the attribute is never expected to be stabilized. Please see RFC #1445 for more details.

cc https://github.com/rust-lang/rust/issues/31434

r? @pnkfelix
2016-03-26 09:07:21 +05:30
Niko Matsakis
e539b74f54 use new visitor to erase regions 2016-03-25 13:10:45 -04:00
Niko Matsakis
f69eb8efbe issue a future-compat lint for constants of invalid type
This is a [breaking-change]: according to RFC #1445, constants used as
patterns must be of a type that *derives* `Eq`. If you encounter a
problem, you are most likely using a constant in an expression where the
type of the constant is some struct that does not currently implement
`Eq`. Something like the following:

```rust
struct SomeType { ... }
const SOME_CONST: SomeType = ...;

match foo {
    SOME_CONST => ...
}
```

The easiest and most future compatible fix is to annotate the type in
question with `#[derive(Eq)]` (note that merely *implementing* `Eq` is
not enough, it must be *derived*):

```rust
struct SomeType { ... }
const SOME_CONST: SomeType = ...;

match foo {
    SOME_CONST => ...
}
```

Another good option is to rewrite the match arm to use an `if`
condition (this is also particularly good for floating point types,
which implement `PartialEq` but not `Eq`):

```rust
match foo {
    c if c == SOME_CONST => ...
}
```

Finally, a third alternative is to tag the type with
`#[structural_match]`; but this is not recommended, as the attribute is
never expected to be stabilized. Please see RFC #1445 for more details.
2016-03-25 06:45:42 -04:00
Niko Matsakis
5bc2868060 make const_expr_to_pat fallible (but never have it actually fail) 2016-03-25 06:44:14 -04:00
Niko Matsakis
0769865f7f rewrite scope drop to be iterative
while I'm at it, remove the "extra caching" that I was doing for no good
reason except laziness. Basically before I was caching at each scope in
the chain, but there's not really a reason to do that, since the cached
entry point at level N is always equal to the last cached exit point
from level N-1.
2016-03-23 20:46:38 -04:00
Niko Matsakis
a276e755e7 introduce "call-site-scope" as the outermost scope
also, when exiting a scope, assign the final goto terminator with the
target scope's id
2016-03-23 16:42:55 -04:00
Niko Matsakis
2b96cfb143 add comments on remaining fields 2016-03-23 16:42:54 -04:00
Niko Matsakis
c36707a284 Add ScopeAuxiliaryVec, return MIR+aux via tuple
It's nice to be able to index with a scope-id,
but coherence rules prevent us from implementing
`Index<ScopeId>` for `Vec<ScopeAuxiliary>`, and I'd
prefer that `ScopeAuxiliary` remain in librustc_mir,
just for compilation time reasons.
2016-03-23 16:42:54 -04:00
Niko Matsakis
70d0123082 Address nit: Remove ScopedDataVec newtype 2016-03-23 16:42:54 -04:00
Niko Matsakis
b3d2059b08 Address nit: block.unit() 2016-03-23 16:42:54 -04:00
Niko Matsakis
c1a53a60e7 Address nit: doc-comments on fields 2016-03-23 16:42:54 -04:00
Niko Matsakis
14a5657a9a Rename MirPlusPlus to MirAndScopeAuxiliary 2016-03-23 16:42:53 -04:00
Niko Matsakis
f66fd8972f replace DUMMY_SP on resume with span from fn 2016-03-23 16:42:53 -04:00
Niko Matsakis
cb04e495dc rewrite drop code
This was triggered by me wanting to address a use of DUMMY_SP, but
actually I'm not sure what would be a better span -- I guess the span
for the function as a whole.
2016-03-23 16:42:53 -04:00
Niko Matsakis
f976e222e9 fix bug in simplify_cfg with inf. loops 2016-03-23 16:42:53 -04:00
Niko Matsakis
a61c1759c7 allow dumping intermediate IR with -Z dump-mir 2016-03-23 16:42:53 -04:00
Niko Matsakis
0d93989cf5 adjust pretty printer to print scopes / auxiliary 2016-03-23 16:42:53 -04:00
Niko Matsakis
d32bde3311 augment MIR pretty printer to print scopes 2016-03-23 16:42:52 -04:00
Niko Matsakis
caac0b969f reformat mir text pretty printer 2016-03-23 16:42:52 -04:00
Niko Matsakis
9d00deee96 add span/scope-id to terminator 2016-03-23 16:42:52 -04:00
Niko Matsakis
3a16f57fbb extend Terminator into a struct so it can have additional fields 2016-03-23 16:42:52 -04:00
Niko Matsakis
e752d4cde3 track the innermost scope for every stmt 2016-03-23 16:37:48 -04:00
Niko Matsakis
323d7f4e98 record a scope for each VarDecl 2016-03-23 16:37:48 -04:00
Niko Matsakis
464c02e336 integrate scopes into MIR 2016-03-23 16:37:48 -04:00
Jorge Aparicio
2628f3cc8f fix alignment 2016-03-22 22:03:54 -05:00
Jorge Aparicio
aa7fe93d4a sprinkle feature gates here and there 2016-03-22 22:02:47 -05:00
Jorge Aparicio
0f02309e4b try! -> ?
Automated conversion using the untry tool [1] and the following command:

```
$ find -name '*.rs' -type f | xargs untry
```

at the root of the Rust repo.

[1]: https://github.com/japaric/untry
2016-03-22 22:01:37 -05:00
Felix S. Klock II
5757e65f7a scaffolding for borrowck on MIR.
emit (via debug!) scary message from `fn borrowck_mir` until basic
prototype is in place.

Gather children of move paths and set their kill bits in
dataflow. (Each node has a link to the child that is first among its
siblings.)

Hooked in libgraphviz based rendering, including of borrowck dataflow
state.

doing this well required some refactoring of the code, so I cleaned it
up more generally (adding comments to explain what its trying to do
and how it is doing it).

Update: this newer version addresses most review comments (at least
the ones that were largely mechanical changes), but I left the more
interesting revisions to separate followup commits (in this same PR).
2016-03-21 18:36:22 +01:00
Felix S. Klock II
213d57983d Expose attached attributes to FnKind abstraction so that I can look at them in borrowck. 2016-03-21 18:36:22 +01:00
Eduard Burtescu
5f990fb4f0 mir: Don't forget to drop arguments. 2016-03-17 22:48:07 +02:00
Eduard Burtescu
7912f94b2d const_eval: Take just one set of substitutions in lookup_const_by_id. 2016-03-17 22:48:07 +02:00
Eduard Burtescu
856185dbb2 hir, mir: Separate HIR expressions / MIR operands from InlineAsm. 2016-03-17 21:51:55 +02:00
Eduard Burtescu
aca4f9396d mir: Get the right non-reference type for binding patterns. 2016-03-17 21:51:55 +02:00
Eduard Burtescu
cf4daf7889 mir: Don't lose sub-patterns inside slice patterns. 2016-03-17 21:51:55 +02:00
Eduard Burtescu
41499f4563 mir: Match against slices by calling PartialEq::eq. 2016-03-17 21:51:55 +02:00
Eduard Burtescu
b63a5eed6e mir: Support RustCall ABI functions. 2016-03-17 21:51:53 +02:00
Eduard Burtescu
d3a6d67fb8 mir: Don't use ConstVal when adjustments are involved, as they would be lost. 2016-03-17 21:51:53 +02:00
Eduard Burtescu
9cc5ee359a mir: Unsize ConstVal::ByteStr before comparing &[u8] against it. 2016-03-17 21:51:53 +02:00
Eduard Burtescu
ccc5e0732a mir: Ignore noop casts (e.g. when as used for coercion). 2016-03-17 21:51:53 +02:00
Eduard Burtescu
1de6a9682f mir: Don't use ConstVal kinds that contain local NodeId's. 2016-03-17 21:51:53 +02:00
Aaron Turon
e5753b4605 Fixes after rebase 2016-03-14 15:05:15 -07:00
Aaron Turon
35437c7cf6 Fixes after a rebase 2016-03-14 15:05:14 -07:00
Aaron Turon
9bcfdb7b9c Move projection_mode to InferContext rather than SelectionContext to reduce chance of bugs 2016-03-14 15:05:13 -07:00
bors
01118928fc Auto merge of #30587 - oli-obk:eager_const_eval2, r=nikomatsakis
typestrong const integers

~~It would be great if someone could run crater on this PR, as this has a high danger of breaking valid code~~ Crater ran. Good to go.

----

So this PR does a few things:

1. ~~const eval array values when const evaluating an array expression~~
2. ~~const eval repeat value when const evaluating a repeat expression~~
3. ~~const eval all struct and tuple fields when evaluating a struct/tuple expression~~
4. remove the `ConstVal::Int` and `ConstVal::Uint` variants and replace them with a single enum (`ConstInt`) which has variants for all integral types
  * `usize`/`isize` are also enums with variants for 32 and 64 bit. At creation and various usage steps there are assertions in place checking if the target bitwidth matches with the chosen enum variant
5. enum discriminants (`ty::Disr`) are now `ConstInt`
6. trans has its own `Disr` type now (newtype around `u64`)

This obviously can't be done without breaking changes (the ones that are noticable in stable)
We could probably write lints that find those situations and error on it for a cycle or two. But then again, those situations are rare and really bugs imo anyway:

```rust
let v10 = 10 as i8;
let v4 = 4 as isize;
assert_eq!(v10 << v4 as usize, 160 as i8);
 ```

stops compiling because 160 is not a valid i8

```rust
struct S<T, S> {
    a: T,
    b: u8,
    c: S
}
let s = S { a: 0xff_ff_ff_ffu32, b: 1, c: 0xaa_aa_aa_aa as i32 };
```

stops compiling because `0xaa_aa_aa_aa` is not a valid i32

----

cc @eddyb @pnkfelix

related: https://github.com/rust-lang/rfcs/issues/1071
2016-03-14 11:38:23 -07:00
Oliver Schneider
f665c399a0 rustbuild 2016-03-14 09:29:18 +01:00
bors
c21644ad16 Auto merge of #31916 - nagisa:mir-passmgr-2, r=arielb1
Add Pass manager for MIR

A new PR, since rebasing the original one (https://github.com/rust-lang/rust/pull/31448) properly was a pain. Since then there has been several changes most notable of which:

1. Removed the pretty-printing with `#[rustc_mir(graphviz/pretty)]`, mostly because we now have `--unpretty=mir`, IMHO that’s the direction we should expand this functionality into;
2. Reverted the infercx change done for typeck, because typeck can make an infercx for itself by being a `MirMapPass`

r? @nikomatsakis
2016-03-13 05:33:28 -07:00
Simonas Kazlauskas
bdc176ef6b Implement --unpretty mir-cfg for graphviz output
Also change output for --unpretty mir to output function names in a prettier way.
2016-03-12 19:07:00 +02:00
Oliver Schneider
6992280f00 simplify const path lookup for constants and associated constants 2016-03-10 12:50:13 +01:00
Oliver Schneider
7bde56e149 typestrong constant integers 2016-03-10 12:50:12 +01:00
Eduard Burtescu
8f07f8a4fa trans: Reify functions & methods to fn ptrs only where necessary. 2016-03-09 16:45:28 +02:00
Eduard Burtescu
ffa0860467 Track fn type and lifetime parameters in TyFnDef. 2016-03-09 16:45:28 +02:00
Eli Friedman
b423a0f9ef Split TyBareFn into TyFnDef and TyFnPtr.
There's a lot of stuff wrong with the representation of these types:
TyFnDef doesn't actually uniquely identify a function, TyFnPtr is used to
represent method calls, TyFnDef in the sub-expression of a cast isn't
correctly reified, and probably some other stuff I haven't discovered yet.
Splitting them seems like the right first step, though.
2016-03-09 16:45:28 +02:00
bors
a9ffe67f98 Auto merge of #31606 - Ms2ger:ClosureKind, r=eddyb
Rename ClosureKind variants and stop re-exporting them.
2016-03-07 22:57:38 -08:00
Simonas Kazlauskas
e30ff06756 Change MirPass to also take NodeId 2016-03-07 23:21:39 +02:00
bors
8484831d29 Auto merge of #30884 - durka:inclusive-ranges, r=aturon
This PR implements [RFC 1192](https://github.com/rust-lang/rfcs/blob/master/text/1192-inclusive-ranges.md), which is triple-dot syntax for inclusive range expressions. The new stuff is behind two feature gates (one for the syntax and one for the std::ops types). This replaces the deprecated functionality in std::iter. Along the way I simplified the desugaring for all ranges.

This is my first contribution to rust which changes more than one character outside of a test or comment, so please review carefully! Some of the individual commit messages have more of my notes. Also thanks for putting up with my dumb questions in #rust-internals.

- For implementing `std::ops::RangeInclusive`, I took @Stebalien's suggestion from https://github.com/rust-lang/rfcs/pull/1192#issuecomment-137864421. It seemed to me to make the implementation easier and increase type safety. If that stands, the RFC should be amended to avoid confusion.
- I also kind of like @glaebhoerl's [idea](https://github.com/rust-lang/rfcs/pull/1254#issuecomment-147815299), which is unified inclusive/exclusive range syntax something like `x>..=y`. We can experiment with this while everything is behind a feature gate.
- There are a couple of FIXMEs left (see the last commit). I didn't know what to do about `RangeArgument` and I haven't added `Index` impls yet. Those should be discussed/finished before merging.

cc @Gankro since you [complained](https://www.reddit.com/r/rust/comments/3xkfro/what_happened_to_inclusive_ranges/cy5j0yq)
cc #27777 #30877 rust-lang/rust#1192 rust-lang/rfcs#1254
relevant to #28237 (tracking issue)
2016-03-06 07:16:41 +00:00
Simonas Kazlauskas
27d91d73f9 Address comments 2016-03-04 15:20:42 +02:00
Simonas Kazlauskas
811b874716 Add Pass manager for MIR 2016-03-04 15:20:10 +02:00
Jeffrey Seyfried
37ba66a66e Rename middle::ty::ctxt to TyCtxt 2016-03-03 07:37:56 +00:00
bors
339a409bfd Auto merge of #31430 - nagisa:mir-dyndrop, r=nikomatsakis
Zeroing on-drop seems to work fine. Still thinking about the best way to approach zeroing on-move.

(based on top of the other drop PR; only the last 2 commits are relevant)
2016-03-01 23:30:49 +00:00
Alex Burka
d792183fde fallout from removing hir::ExprRange
A whole bunch of stuff gets folded into struct handling! Plus, removes
an ugly hack from trans and accidentally fixes a bug with constructing
ranges from references (see later commits with tests).
2016-02-27 02:01:41 -05:00
Simonas Kazlauskas
d1a12392b2 Nits and cleanups 2016-02-26 14:15:38 +02:00
Simonas Kazlauskas
77be4ecc17 Make list of statements flat
In MIR we previously tried to match `let x in { exprs; let y in { exprs; }}` with our data
structures which is rather unwieldy, espeicially because it requires some sort of recursion or
stack to process, while, a flat list of statements is enough – lets only relinquish their lifetime
at the end of the block (i.e. end of the list).

Also fixes #31853.
2016-02-24 22:04:22 +02:00
Simonas Kazlauskas
b92e2437f5 [MIR] Change SimplifyCfg pass to use bitvec
BitVector is much more space efficient.
2016-02-23 11:43:52 +02:00
Ariel Ben-Yehuda
d84658e317 address review comments 2016-02-20 13:17:30 +02:00
Ariel Ben-Yehuda
881249aa46 use the FulfillmentContext and InferCtxt more correctly 2016-02-20 02:02:53 +02:00
Ariel Ben-Yehuda
a61963ab08 TODO -> FIXME 2016-02-20 01:54:58 +02:00
Ariel Ben-Yehuda
ae919d0f4b type-check lvalues 2016-02-20 01:54:58 +02:00
Ariel Ben-Yehuda
880b6c260a fix a few remaining bugs - make check runs! 2016-02-20 01:54:58 +02:00
Ariel Ben-Yehuda
3c6f41026b store the normalized types of field accesses
Fixes #31504
2016-02-20 01:54:58 +02:00
Ariel Ben-Yehuda
350b50df00 deref the argument of overloaded MIR autoderef
Fixes #31466
2016-02-20 01:54:58 +02:00
Ariel Ben-Yehuda
76608c8e0a make *mut T -> *const T a coercion
rather than being implicit quasi-subtyping. Nothing good can come out
of quasi-subtyping.
2016-02-20 01:54:58 +02:00
Ariel Ben-Yehuda
6f633ef128 tuple arguments to overloaded calls
also fix translation of "rust-call" functions, although that could use
more optimizations
2016-02-20 01:54:58 +02:00
Ariel Ben-Yehuda
b7cbbc374c be more type-safe in panic/panic_bounds_check
TODO: find a correct borrow region

Fixes #31482
2016-02-20 01:45:13 +02:00
Ariel Ben-Yehuda
67d1cf1122 introduce an early pass to clear dead blocks
this makes the the MIR assignment pass complete successfully
2016-02-20 01:45:13 +02:00
Ariel Ben-Yehuda
999f1767ca add -Z mir-opt-level to disable MIR optimizations
setting -Z mir-opt-level=0 will disable all MIR optimizations
for easier debugging
2016-02-20 01:38:27 +02:00
Ariel Ben-Yehuda
addc653da5 begin implementing mir-typeck 2016-02-19 19:13:53 +02:00
bors
de366b5218 Auto merge of #31600 - nagisa:mir-msvc-seh-2, r=nikomatsakis
r? @alexcrichton for the translator changes and @nikomatsakis for the no-landing-pads pass.
2016-02-18 20:46:28 +00:00
Simonas Kazlauskas
1752615591 MSVC SEH in MIR is implemented here 2016-02-17 21:46:05 +02:00
Vadim Petrochenkov
06755d90ce Split PatKind::Enum into PatKind::TupleStruct and PatKind::Path 2016-02-16 00:40:38 +03:00
Vadim Petrochenkov
9b40e1e5b3 Rename hir::Pat_ and its variants 2016-02-14 15:25:12 +03:00
bors
1ab22d77f9 Auto merge of #31564 - durka:lang-item-icemelt, r=nikomatsakis
This changes three ICEs to fatal errors.

I've grepped for `lang_item.*expect` and `\.expect.*lang` and didn't come up with any more. But, there could be more ICEs lurking.

I wasn't sure about a test because there already _is_ a cfail test for missing lang items, but it only checks one.

Relevant to (already closed) #31477 #31480 #31558.
cc @lilred
2016-02-13 10:23:49 +00:00
Jonas Schievink
53b7464e67 Autoderef in librustc_mir 2016-02-12 19:28:42 +01:00
Ms2ger
c6474af96f Rename ClosureKind variants and stop re-exporting them. 2016-02-12 16:44:27 +01:00
Simonas Kazlauskas
5ad4673a40 Add a no-landing-pads MIR pass
The pass removes the unwind branch of each terminator, thus moving the responsibility of handling
the -Z no-landing-pads flag to a small self-contained pass… instead of polluting the translator.
2016-02-11 23:13:55 +02:00
Alex Crichton
2581b14147 bootstrap: Add a bunch of Cargo.toml files
These describe the structure of all our crate dependencies.
2016-02-11 11:12:32 -08:00
Alex Burka
e13d352aaf don't ICE on missing box_free lang item 2016-02-11 01:37:55 -05:00
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
Scott Olson
080994a189 Add 'mut' to MIR temp variable debug output. 2016-01-04 16:11:33 -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
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
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
Scott Olson
56343cd653 Add 'mut' to temporary vars in MIR graphviz output. 2016-01-02 07:12:35 -06:00
Simonas Kazlauskas
add7410af6 Fix equality checks in matches 2016-01-01 14:55:57 +02:00
Wesley Wiser
8c897ee0ab Avoid adding drops for types w/ no dtor in MIR construction
Fixes #28159
2015-12-31 17:05:08 -05:00
Simonas Kazlauskas
7448f4861a 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;

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

     bb1: {
         return;
     }

     bb2: {
         diverge;
     }
 }
```

(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.)
2015-12-31 18:52:20 +02:00
Scott Olson
8a834097cc Use built-in comparisons for range matching in MIR.
The previous version using `PartialOrd::le` was broken since it passed `T`
arguments where `&T` was expected.

It makes sense to use primitive comparisons since range patterns can only be
used with chars and numeric types.
2015-12-30 10:25:41 -06:00
Scott Olson
f8b61340e3 Refactor MIR building for arguments. 2015-12-30 06:55:51 -06:00
Scott Olson
b65277496c Fix argument indices in MIR for closures.
Previously, all references to closure arguments went to the argument before the
one they should (e.g. to arg1 when it was supposed to be 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.
2015-12-29 22:55:38 -06:00
Scott Olson
31578f5bbf Fix MIR var names and keep them in sync. 2015-12-29 20:32:37 -06:00
Luqman Aden
f88c808b73 Process candidates for match in the same order as written in the source. 2015-12-29 17:03:56 -05:00
Scott Olson
e69713db9e Add comments and simplify MIR graphviz code. 2015-12-28 17:17:53 -06:00
Scott Olson
9000ecf761 Rewrite MIR graphviz printing and improve MIR debug printing. 2015-12-28 17:17:53 -06:00
Simonas Kazlauskas
7b68b5fc2a Also fix MIRification of unit enum variants 2015-12-26 14:44:36 +02:00
Luqman Aden
0a09ae6de8 [MIR] Make sure candidates are reversed before match_candidates. 2015-12-24 22:07:11 -05:00