Rollup merge of #33342 - birkenfeld:issue-26472, r=jseyfried
typeck: if a private field exists, also check for a public method
For example, `Vec::len` is both a field and a method, and usually encountering `vec.len` just means that the parens were forgotten.
Fixes: #26472
NOTE: I added the parameter `allow_private` to `method::exists` since I don't want to suggest inaccessible methods. For the second case, where only the method exists, I think it would make sense to set it to `false` as well, but I wanted to preserve compatibility for this case.
bors [Sun, 15 May 2016 08:14:10 +0000 (01:14 -0700)]
Auto merge of #33607 - jonas-schievink:prettier-mir, r=eddyb
Some simple improvements to MIR pretty printing
In short, this PR changes the MIR printer so that it:
* places an empty line between the MIR for each item
* does *not* write an empty line before the first BB when there are no
var decls
* aligns the "// Scope" comments 50 chars in (makes the output more
readable)
* prints the scope comments as "// scope N at ..." instead of "//
Scope(N) at ..."
* prints a prettier scope tree:
* no more unbalanced delimiters!
* no more "Parent" entry (these convey no useful information)
* drop the "Scope()" and just print scope IDs
* no braces when the scope is empty
bors [Sun, 15 May 2016 05:04:58 +0000 (22:04 -0700)]
Auto merge of #33593 - dotdash:smart_derive, r=brson
Improve derived implementations for enums with lots of fieldless variants
A number of trait methods like PartialEq::eq or Hash::hash don't
actually need a distinct arm for each variant, because the code within
the arm only depends on the number and types of the fields in the
variants. We can easily exploit this fact to create less and better
code for enums with multiple variants that have no fields at all, the
extreme case being C-like enums.
For nickel.rs and its by now infamous 800 variant enum, this reduces
optimized compile times by 25% and non-optimized compile times by 40%.
Also peak memory usage is down by almost 40% (310MB down to 190MB).
To be fair, most other crates don't benefit nearly as much, because
they don't have as huge enums. The crates in the Rust distribution that
I measured saw basically no change in compile times (I only tried
optimized builds) and only 1-2% reduction in peak memory usage.
bors [Sat, 14 May 2016 18:56:58 +0000 (11:56 -0700)]
Auto merge of #33579 - Amanieu:atomic_bool2, r=alexcrichton
Make AtomicBool the same size as bool
Reopening #32365
This allows `AtomicBool` to be transmuted to a `bool`, which makes it more consistent with the other atomic types. Note that this now guarantees that the atomic type will always contain a valid `bool` value, which wasn't the case before (due to `fetch_nand`).
Rollup merge of #33566 - dotdash:biased_switch, r=nagisa
[MIR trans] Optimize trans for biased switches
Currently, all switches in MIR are exhausitive, meaning that we can have
a lot of arms that all go to the same basic block, the extreme case
being an if-let expression which results in just 2 possible cases, be
might end up with hundreds of arms for large enums.
To improve this situation and give LLVM less code to chew on, we can
detect whether there's a pre-dominant target basic block in a switch
and then promote this to be the default target, not translating the
corresponding arms at all.
In combination with #33544 this makes unoptimized MIR trans of
nickel.rs as fast as using old trans and greatly improves the times for
optimized builds, which are only 30-40% slower instead of ~300%.
Rollup merge of #33555 - soltanmm:ambiguous-nixon, r=nikomatsakis
Remove unification despite ambiguity in projection
Turns out that closures aren't explicitly considered in `project.rs`, so the ambiguity handling w.r.t. closures can just be removed as the change done in `select.rs` covers it.
Rollup merge of #33544 - dotdash:baby_dont_break_me_no_more, r=Aatch
Only break critical edges where actually needed
Currently, to prepare for MIR trans, we break _all_ critical edges,
although we only actually need to do this for edges originating from a
call that gets translated to an invoke instruction in LLVM.
This has the unfortunate effect of undoing a bunch of the things that
SimplifyCfg has done. A particularly bad case arises when you have a
C-like enum with N variants and a derived PartialEq implementation.
In that case, the match on the (&lhs, &rhs) tuple gets translated into
nested matches with N arms each and a basic block each, resulting in N²
basic blocks. SimplifyCfg reduces that to roughly 2*N basic blocks, but
breaking the critical edges means that we go back to N².
In nickel.rs, there is such an enum with roughly N=800. So we get about
640K basic blocks or 2.5M lines of LLVM IR. LLVM takes a while to
reduce that to the final "disr_a == disr_b".
So before this patch, we had 2.5M lines of IR with 640K basic blocks,
which took about about 3.6s in LLVM to get optimized and translated.
After this patch, we get about 650K lines with about 1.6K basic blocks
and spent a little less than 0.2s in LLVM.
bors [Sat, 14 May 2016 01:40:08 +0000 (18:40 -0700)]
Auto merge of #33532 - jseyfried:mutable_lowering_context, r=nrc
Clean up `hir::lowering`
Clean up `hir::lowering`:
- give lowering functions mutable access to the lowering context
- refactor the `lower_*` functions and other functions that take a lowering context into methods
- simplify the API that `hir::lowering` exposes to `driver`
- other miscellaneous cleanups
bors [Fri, 13 May 2016 23:00:05 +0000 (16:00 -0700)]
Auto merge of #33508 - alexcrichton:always-lower-frem, r=nikomatsakis
trans: Always lower to `frem`
Long ago LLVM unfortunately didn't handle the 32-bit MSVC case of `frem` where
it can't be lowered to `fmodf` because that symbol doesn't exist. That was since
fixed in http://reviews.llvm.org/D12099 (landed as r246615) and was released in
what appears to be LLVM 3.8. Now that we're using that branch of LLVM let's
remove our own hacks and help LLVM optimize a little better by giving it
knowledge about what we're doing.
bors [Fri, 13 May 2016 15:46:16 +0000 (08:46 -0700)]
Auto merge of #33531 - antonblanchard:local_stage0_fix, r=alexcrichton
Copy more libraries from local Rust to stage0
When bootstrapping Rust using a previously built toolchain, I noticed
a number of libraries were not copied in. As a result the copied in
rustc fails to execute because it can't find all its dependences.
bors [Fri, 13 May 2016 10:10:46 +0000 (03:10 -0700)]
Auto merge of #33541 - eddyb:promote-only-temps, r=arielb1
mir: don't attempt to promote Unpromotable constant temps.
Fixes #33537. This was a non-problem in regular functions, but we also promote in `const fn`s.
There we always qualify temps so you can't depend on `Unpromotable` temps being `NOT_CONST`.
bors [Fri, 13 May 2016 07:29:22 +0000 (00:29 -0700)]
Auto merge of #33596 - nikomatsakis:issue-33586-regr-assoc-type-path, r=eddyb
re-introduce a cache for ast-ty-to-ty
It turns out that `ast_ty_to_ty` is supposed to be updating the `def`
after it finishes, but at some point in the past it stopped doing
so. This was never noticed because of the `ast_ty_to_ty_cache`, but that
cache was recently removed. This PR fixes the code to update the def
properly, but apparently that is not quite enough to make the operation
idempotent, so for now we reintroduce the cache too.
Jonas Schievink [Thu, 12 May 2016 22:20:59 +0000 (00:20 +0200)]
Some simple improvements to MIR pretty printing
In short, this PR changes the MIR printer so that it:
* places an empty line between the MIR for each item
* does *not* write an empty line before the first BB when there are no
var decls
* aligns the "// Scope" comments 50 chars in (makes the output more
readable)
* prints the scope comments as "// scope N at ..." instead of "//
Scope(N) at ..."
* prints a prettier scope tree:
* no more unbalanced delimiters!
* no more "Parent" entry (these convey no useful information)
* drop the "Scope()" and just print scope IDs
* no braces when the scope is empty
bors [Thu, 12 May 2016 21:31:54 +0000 (14:31 -0700)]
Auto merge of #33282 - alexcrichton:rustbuild-crate-tests, r=brson
rustbuild: Add support for crate tests + doctests
This commit adds support to rustbuild to run crate unit tests (those defined by
`#[test]`) as well as documentation tests. All tests are powered by `cargo test`
under the hood.
Each step requires the `libtest` library is built for that corresponding stage.
Ideally the `test` crate would be a dev-dependency, but for now it's just easier
to ensure that we sequence everything in the right order.
Currently no filtering is implemented, so there's not actually a method of
testing *only* libstd or *only* libcore, but rather entire swaths of crates are
tested all at once.
A few points of note here are:
* The `coretest` and `collectionstest` crates are just listed as `[[test]]`
entires for `cargo test` to naturally pick up. This mean that `cargo test -p
core` actually runs all the tests for libcore.
* Libraries that aren't tested all mention `test = false` in their `Cargo.toml`
* Crates aren't currently allowed to have dev-dependencies due to
rust-lang/cargo#860, but we can likely alleviate this restriction once
workspaces are implemented.
Björn Steinbrink [Thu, 12 May 2016 15:54:05 +0000 (17:54 +0200)]
Improve derived implementations for enums with lots of fieldless variants
A number of trait methods like PartialEq::eq or Hash::hash don't
actually need a distinct arm for each variant, because the code within
the arm only depends on the number and types of the fields in the
variants. We can easily exploit this fact to create less and better
code for enums with multiple variants that have no fields at all, the
extreme case being C-like enums.
For nickel.rs and its by now infamous 800 variant enum, this reduces
optimized compile times by 25% and non-optimized compile times by 40%.
Also peak memory usage is down by almost 40% (310MB down to 190MB).
To be fair, most other crates don't benefit nearly as much, because
they don't have as huge enums. The crates in the Rust distribution that
I measured saw basically no change in compile times (I only tried
optimized builds) and only 1-2% reduction in peak memory usage.
Niko Matsakis [Thu, 12 May 2016 18:19:26 +0000 (14:19 -0400)]
re-introduce a cache for ast-ty-to-ty
It turns out that `ast_ty_to_ty` is supposed to be updating the `def`
after it finishes, but at some point in the past it stopped doing
so. This was never noticed because of the `ast_ty_to_ty_cache`, but that
cache was recently removed. This PR fixes the code to update the def
properly, but apparently that is not quite enough to make the operation
idempotent, so for now we reintroduce the cache too.
Alex Crichton [Fri, 29 Apr 2016 21:23:15 +0000 (14:23 -0700)]
rustbuild: Add support for crate tests + doctests
This commit adds support to rustbuild to run crate unit tests (those defined by
`#[test]`) as well as documentation tests. All tests are powered by `cargo test`
under the hood.
Each step requires the `libtest` library is built for that corresponding stage.
Ideally the `test` crate would be a dev-dependency, but for now it's just easier
to ensure that we sequence everything in the right order.
Currently no filtering is implemented, so there's not actually a method of
testing *only* libstd or *only* libcore, but rather entire swaths of crates are
tested all at once.
A few points of note here are:
* The `coretest` and `collectionstest` crates are just listed as `[[test]]`
entires for `cargo test` to naturally pick up. This mean that `cargo test -p
core` actually runs all the tests for libcore.
* Libraries that aren't tested all mention `test = false` in their `Cargo.toml`
* Crates aren't currently allowed to have dev-dependencies due to
rust-lang/cargo#860, but we can likely alleviate this restriction once
workspaces are implemented.
bors [Thu, 12 May 2016 02:48:54 +0000 (19:48 -0700)]
Auto merge of #33169 - swgillespie:issue32829, r=eddyb
const_fn: Check the terminating expression of a block for blocks in a const initializer
In a const or static initializer, the `CheckBlock` check ensures that blocks in the initializer expression are only in tail positions or in items. In this case, it didn't check the terminating expression of a block, which resulted in an ICE later in the compiler pipeline if the trailing expression was itself a block. This change fixes the ICE and ensures that the proper error is emitted. This fixes the ICE in #32829 .
Björn Steinbrink [Wed, 11 May 2016 19:31:19 +0000 (21:31 +0200)]
[MIR trans] Optimize trans for biased switches
Currently, all switches in MIR are exhausitive, meaning that we can have
a lot of arms that all go to the same basic block, the extreme case
being an if-let expression which results in just 2 possible cases, be
might end up with hundreds of arms for large enums.
To improve this situation and give LLVM less code to chew on, we can
detect whether there's a pre-dominant target basic block in a switch
and then promote this to be the default target, not translating the
corresponding arms at all.
In combination with #33544 this makes unoptimized MIR trans of
nickel.rs as fast as using old trans and greatly improves the times for
optimized builds, which are only 30-40% slower instead of ~300%.
Guillaume Gomez [Wed, 11 May 2016 19:30:20 +0000 (21:30 +0200)]
Rollup merge of #33558 - bnewbold:trivial-book-tweaks, r=steveklabnik
trivial tweaks to documentation (book)
These are small things I found while reading through The Book. The `<hash>` and `panic!` lines are simply to improve readability, while I believe the proceeding/following distinction is a bug (but might be a English dialect distinction?).
I've read `rust/CONTRIBUTING`, i'm not sure if there is anything I need to do other than submit this PR.
Björn Steinbrink [Tue, 10 May 2016 19:03:47 +0000 (21:03 +0200)]
Only break critical edges where actually needed
Currently, to prepare for MIR trans, we break _all_ critical edges,
although we only actually need to do this for edges originating from a
call that gets translated to an invoke instruction in LLVM.
This has the unfortunate effect of undoing a bunch of the things that
SimplifyCfg has done. A particularly bad case arises when you have a
C-like enum with N variants and a derived PartialEq implementation.
In that case, the match on the (&lhs, &rhs) tuple gets translated into
nested matches with N arms each and a basic block each, resulting in N²
basic blocks. SimplifyCfg reduces that to roughly 2*N basic blocks, but
breaking the critical edges means that we go back to N².
In nickel.rs, there is such an enum with roughly N=800. So we get about
640K basic blocks or 2.5M lines of LLVM IR. LLVM takes a while to
reduce that to the final "disr_a == disr_b".
So before this patch, we had 2.5M lines of IR with 640K basic blocks,
which took about about 3.6s in LLVM to get optimized and translated.
After this patch, we get about 650K lines with about 1.6K basic blocks
and spent a little less than 0.2s in LLVM.
Steve Klabnik [Wed, 11 May 2016 13:27:43 +0000 (09:27 -0400)]
Rollup merge of #33345 - birkenfeld:issue-31754, r=pnkfelix
middle: reset loop labels while visiting closure
This should fix #31754 and follow-up #25343. Before the latter, the closure was visited twice in the context of the enclosing fn, which made even a single closure with a loop label emit a warning.
With this change, the closure is still visited within the context of the main fn (which is intended, since it is not a separate item) but resets the found loop labels while being visited.
Fixes: #31754
Note: I amended the test file from #25343, but I don't know if the original or amended test are effective, since as far as I could see, compiletest's run-pass tests do not check for zero warnings emitted?