Aaron Hill [Tue, 30 Jan 2018 04:15:38 +0000 (23:15 -0500)]
Fix ref-to-ptr coercions not working with NLL in certain cases
Implicit coercions from references to pointers were lowered to slightly
different Mir than explicit casts (e.g. 'foo as *mut T'). This resulted
in certain uses of self-referential structs compiling correctly when an
explicit cast was used, but not when the implicit coercion was used.
To fix this, this commit adds an outer 'Use' expr when applying a
raw-ptr-borrow adjustment. This makes the lowered Mir for coercions
identical to that of explicit coercions, allowing the original code to
compile regardless of how the raw ptr cast occurs.
bors [Mon, 29 Jan 2018 04:55:47 +0000 (04:55 +0000)]
Auto merge of #47730 - alexcrichton:multitrans, r=Mark-Simulacrum
rustc: Split Emscripten to a separate codegen backend
This commit introduces a separately compiled backend for Emscripten, avoiding
compiling the `JSBackend` target in the main LLVM codegen backend. This builds
on the foundation provided by #47671 to create a new codegen backend dedicated
solely to Emscripten, removing the `JSBackend` of the main codegen backend in
the process.
A new field was added to each target for this commit which specifies the backend
to use for translation, the default being `llvm` which is the main backend that
we use. The Emscripten targets specify an `emscripten` backend instead of the
main `llvm` one.
There's a whole bunch of consequences of this change, but I'll try to enumerate
them here:
* A *second* LLVM submodule was added in this commit. The main LLVM submodule
will soon start to drift from the Emscripten submodule, but currently they're
both at the same revision.
* Logic was added to rustbuild to *not* build the Emscripten backend by default.
This is gated behind a `--enable-emscripten` flag to the configure script. By
default users should neither check out the emscripten submodule nor compile
it.
* The `init_repo.sh` script was updated to fetch the Emscripten submodule from
GitHub the same way we do the main LLVM submodule (a tarball fetch).
* The Emscripten backend, turned off by default, is still turned on for a number
of targets on CI. We'll only be shipping an Emscripten backend with Tier 1
platforms, though. All cross-compiled platforms will not be receiving an
Emscripten backend yet.
This commit means that when you download the `rustc` package in Rustup for Tier
1 platforms you'll be receiving two trans backends, one for Emscripten and one
that's the general LLVM backend. If you never compile for Emscripten you'll
never use the Emscripten backend, so we may update this one day to only download
the Emscripten backend when you add the Emscripten target. For now though it's
just an extra 10MB gzip'd.
Alex Crichton [Wed, 24 Jan 2018 16:22:34 +0000 (08:22 -0800)]
rustc: Split Emscripten to a separate codegen backend
This commit introduces a separately compiled backend for Emscripten, avoiding
compiling the `JSBackend` target in the main LLVM codegen backend. This builds
on the foundation provided by #47671 to create a new codegen backend dedicated
solely to Emscripten, removing the `JSBackend` of the main codegen backend in
the process.
A new field was added to each target for this commit which specifies the backend
to use for translation, the default being `llvm` which is the main backend that
we use. The Emscripten targets specify an `emscripten` backend instead of the
main `llvm` one.
There's a whole bunch of consequences of this change, but I'll try to enumerate
them here:
* A *second* LLVM submodule was added in this commit. The main LLVM submodule
will soon start to drift from the Emscripten submodule, but currently they're
both at the same revision.
* Logic was added to rustbuild to *not* build the Emscripten backend by default.
This is gated behind a `--enable-emscripten` flag to the configure script. By
default users should neither check out the emscripten submodule nor compile
it.
* The `init_repo.sh` script was updated to fetch the Emscripten submodule from
GitHub the same way we do the main LLVM submodule (a tarball fetch).
* The Emscripten backend, turned off by default, is still turned on for a number
of targets on CI. We'll only be shipping an Emscripten backend with Tier 1
platforms, though. All cross-compiled platforms will not be receiving an
Emscripten backend yet.
This commit means that when you download the `rustc` package in Rustup for Tier
1 platforms you'll be receiving two trans backends, one for Emscripten and one
that's the general LLVM backend. If you never compile for Emscripten you'll
never use the Emscripten backend, so we may update this one day to only download
the Emscripten backend when you add the Emscripten target. For now though it's
just an extra 10MB gzip'd.
bors [Sun, 28 Jan 2018 23:30:15 +0000 (23:30 +0000)]
Auto merge of #47663 - malbarbo:mips-crt-static, r=alexcrichton
Do not assume dynamic linking for musl/mips[el] targets
All musl targets except mips[el] assume static linking by default. This can be [confusing](https://users.rust-lang.org/t/static-cross-compiled-binaries-arent-really-static/6084).
When the musl/mips[el] targets was [added](https://github.com/rust-lang/rust/pull/31298), dynamic linking was chosen because of binary size concerns, and probably also because libunwind [didn't](https://users.rust-lang.org/t/static-cross-compiled-binaries-arent-really-static/6084/8) supported mips.
Now that we have `crt-static` target-feature (the user can choose dynamic link for musl targets), and libunwind [6.0](https://github.com/llvm-mirror/libunwind/commits/release_60) add support to mips, we do not need to assume dynamic linking.
bors [Sun, 28 Jan 2018 13:24:47 +0000 (13:24 +0000)]
Auto merge of #47794 - etaoins:fix-ice-on-const-eval-of-union-field, r=eddyb
Fix ICE on const eval of union field
MIR's `Const::get_field()` attempts to retrieve the value for a given field in a constant. In the case of a union constant it was falling through to a generic `const_get_elt` based on the field index. As union fields don't have an index this caused an ICE in `llvm_field_index`.
Fix by simply returning the current value when accessing any field in a union. This works because all union fields start at byte offset 0.
The added test uses `const_fn` it ensure the field is extracted using MIR's const evaluation. The crash is reproducible without it, however.
bors [Sun, 28 Jan 2018 03:40:26 +0000 (03:40 +0000)]
Auto merge of #47671 - alexcrichton:trans-c-api-only, r=Mark-Simulacrum
rustc: Load the `rustc_trans` crate at runtime
Building on the work of #45684 this commit updates the compiler to
unconditionally load the `rustc_trans` crate at runtime instead of linking to it
at compile time. The end goal of this work is to implement #46819 where rustc
will have multiple backends available to it to load.
This commit starts off by removing the `extern crate rustc_trans` from the
driver. This involved moving some miscellaneous functionality into the
`TransCrate` trait and also required an implementation of how to locate and load
the trans backend. This ended up being a little tricky because the sysroot isn't
always the right location (for example `--sysroot` arguments) so some extra code
was added as well to probe a directory relative to the current dll (the
rustc_driver dll).
Rustbuild has been updated accordingly as well to have a separate compilation
invocation for the `rustc_trans` crate and assembly it accordingly into the
sysroot. Finally, the distribution logic for the `rustc` package was also
updated to slurp up the trans backends folder.
A number of assorted fallout changes were included here as well to ensure tests
pass and such, and they should all be commented inline.
Alex Crichton [Mon, 22 Jan 2018 15:29:24 +0000 (07:29 -0800)]
rustc: Load the `rustc_trans` crate at runtime
Building on the work of # 45684 this commit updates the compiler to
unconditionally load the `rustc_trans` crate at runtime instead of linking to it
at compile time. The end goal of this work is to implement # 46819 where rustc
will have multiple backends available to it to load.
This commit starts off by removing the `extern crate rustc_trans` from the
driver. This involved moving some miscellaneous functionality into the
`TransCrate` trait and also required an implementation of how to locate and load
the trans backend. This ended up being a little tricky because the sysroot isn't
always the right location (for example `--sysroot` arguments) so some extra code
was added as well to probe a directory relative to the current dll (the
rustc_driver dll).
Rustbuild has been updated accordingly as well to have a separate compilation
invocation for the `rustc_trans` crate and assembly it accordingly into the
sysroot. Finally, the distribution logic for the `rustc` package was also
updated to slurp up the trans backends folder.
A number of assorted fallout changes were included here as well to ensure tests
pass and such, and they should all be commented inline.
bors [Sun, 28 Jan 2018 00:40:10 +0000 (00:40 +0000)]
Auto merge of #47746 - varkor:never-type-ice, r=nikomatsakis
Fix never-type rvalue ICE
This fixes #43061.
r? @nikomatsakis
A small post-mortem as a follow-up to our investigations in https://github.com/rust-lang/rust/pull/47291:
The problem as I understand it is that when `NeverToAny` coercions are made, the expression/statement that is coerced may be enclosed in a block. In our case, the statement `x;` was being transformed to something like: `NeverToAny( {x;} )`. Then, `NeverToAny` is transformed into an expression:
https://github.com/rust-lang/rust/blob/000fbbc9b8f88adc6a417f1caef41161f104250f/src/librustc_mir/build/expr/into.rs#L52-L59
Which ends up calling `ast_block_stmts` on the block `{x;}`, which triggers this condition:
https://github.com/rust-lang/rust/blob/000fbbc9b8f88adc6a417f1caef41161f104250f/src/librustc_mir/build/block.rs#L141-L147
In our case, there is no return expression, so `push_assign_unit` is called. But the block has already been recorded as _diverging_, meaning the result of the block will be assigned to a location of type `!`, rather than `()`. This causes the MIR error.
I'm assuming the `NeverToAny` coercion code is doing what it's supposed to (there don't seem to be any other problems), so fixing the issue simply consists of checking that the destination for the return value actually _is_ supposed to be a unit. (If no return value is given, the only other possible type for the return value is `!`, which can just be ignored, as it will be unreachable anyway.)
I checked the other cases of `push_assign_unit`, and it didn't look like they could be affected by the divergence issue (blocks are kind of special-cased in this regard as far as I can tell), so this should be sufficient to fix the issue.
bors [Sat, 27 Jan 2018 10:56:56 +0000 (10:56 +0000)]
Auto merge of #46450 - Gilnaa:libtest_json_output, r=nrc
Libtest json output
A revisit to my [last PR](https://github.com/rust-lang/rust/pull/45923).
Events are now more atomic, printed in a flat hierarchy.
For the normal test output:
```
running 1 test
test f ... FAILED
failures:
---- f stdout ----
thread 'f' panicked at 'assertion failed: `(left == right)`
left: `3`,
right: `4`', f.rs:3:1
note: Run with `RUST_BACKTRACE=1` for a backtrace.
failures:
f
test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out
```
bors [Sat, 27 Jan 2018 08:04:12 +0000 (08:04 +0000)]
Auto merge of #47690 - estebank:for-block-277, r=nikomatsakis
For E0277 on `for` loops, point at the "head" expression
When E0277's span points at a `for` loop, the actual issue is in the
element being iterated. Instead of pointing at the entire loop, point
only at the first line (when possible) so that the span ends in the
element for which E0277 was triggered.
Ryan Cumming [Sat, 27 Jan 2018 01:14:12 +0000 (12:14 +1100)]
Fix ICE on const eval of union field
MIR's `Const::get_field()` attempts to retrieve the value for a given
field in a constant. In the case of a union constant it was falling
through to a generic `const_get_elt` based on the field index. As union
fields don't have an index this caused an ICE in `llvm_field_index`.
Fix by simply returning the current value when accessing any field in a
union. This works because all union fields start at byte offset 0.
The added test uses `const_fn` it ensure the field is extracted using
MIR's const evaluation. The crash is reproducible without it, however.
bors [Sat, 27 Jan 2018 00:28:34 +0000 (00:28 +0000)]
Auto merge of #47571 - FenrirWolf:libunwind, r=alexcrichton
Match libunwind's EABI selection with libpanic_unwind
Currently, the `libunwind` crate will only select the ARM EABI if it is compiling for ARM/Linux or Android targets. `libpanic_unwind`, however, will choose the ARM EABI if the target arch is ARM and the OS is not iOS. This means that if one tries to enable unwinding for a non-standard ARM target (such as implementing a custom stdlib via Xargo, for example), then the two crates can potentially disagree about which EABI is being targeted.
This PR makes `libunwind` use the [same logic](https://github.com/rust-lang/rust/blob/master/src/libpanic_unwind/gcc.rs#L139-L146) as `libpanic_unwind` when choosing the EABI.
I noticed there are a few comments about certain functions only differing on Android or ARM/Linux, but I *think* that those differences apply to the ARM EABI in general. Let me know if I'm wrong about that.
Josh Stone [Fri, 26 Jan 2018 00:22:58 +0000 (16:22 -0800)]
Call non-git beta builds simply x.y.z-beta
We can't use git commands to compute a prerelease version when we're
building from a source tarball, or if git is otherwise unavailable.
We'll just call such builds `x.y.z-beta`, without a prerelease.
Alex Crichton [Thu, 25 Jan 2018 18:49:01 +0000 (12:49 -0600)]
Rollup merge of #47710 - alexcrichton:llvm-6-compat, r=nikomatsakis
First round of LLVM 6.0.0 compatibility
This includes a number of commits for the first round of upgrading to LLVM 6. There are still [lingering bugs](https://github.com/rust-lang/rust/issues/47683) but I believe all of this will nonetheless be necessary!
Alex Crichton [Thu, 25 Jan 2018 18:49:00 +0000 (12:49 -0600)]
Rollup merge of #47705 - pietroalbini:fix-47673, r=petrochenkov
Fix ICE when use trees have multiple empty nested groups
The issue was caused by an oversight of mine in the original use_nested_groups PR, where different paths were resolved with the same `NodeId` in some cases (such as in `use {{}, {}};`).
Alex Crichton [Thu, 25 Jan 2018 18:48:56 +0000 (12:48 -0600)]
Rollup merge of #47656 - ishitatsuyuki:patch-1, r=nikomatsakis
[perf] Use std based dedup in projection
Unstable sort was added recently, and the code that is being modified is 3 years old. As quicksort doesn't allocate it will likely perform as well as, or better than linear search.
Alex Crichton [Thu, 25 Jan 2018 18:48:54 +0000 (12:48 -0600)]
Rollup merge of #47618 - mrhota:dw_at_noreturn, r=michaelwoerister
Teach rustc about DW_AT_noreturn and a few more DIFlags
We achieve two small things with this PR:
1. We provide definitions for a few additional llvm debuginfo flags
1. We _use_ one of these new flags, `FlagNoReturn`, and add it to debuginfo for functions with the never return type (`!`).
Alex Crichton [Thu, 25 Jan 2018 16:00:22 +0000 (08:00 -0800)]
rustc: SIMD types use pointers in Rust's ABI
This commit changes the ABI of SIMD types in the "Rust" ABI to unconditionally
be passed via pointers instead of being passed as immediates. This should fix a
longstanding issue, #44367, where SIMD-using programs ended up showing very odd
behavior at runtime because the ABI between functions was mismatched.
As a bit of a recap, this is sort of an LLVM bug and sort of an LLVM feature
(today's behavior). LLVM will generate code for a function solely looking at the
function it's generating, including calls to other functions. Let's then say
you've got something that looks like:
```llvm
define void @foo() { ; no target features enabled
call void @bar(<i64 x 4> zeroinitializer)
ret void
}
define void @bar(<i64 x 4>) #0 { ; enables the AVX feature
...
}
```
LLVM will codegen the call to `bar` *without* using AVX registers becauase `foo`
doesn't have access to these registers. Instead it's generated with emulation
that uses two 128-bit registers. The `bar` function, on the other hand, will
expect its argument in an AVX register (as it has AVX enabled). This means we've
got a codegen problem!
Comments on #44367 have some more contexutal information but the crux of the
issue is that if we want SIMD to work in general we'll need to ensure that
whenever a function calls another they ABI of the arguments being passed is in
agreement.
One possible solution to this would be to insert "shim functions" where whenever
a `target_feature` mismatch is detected the compiler inserts a shim function
where you pass arguments via memory to the shim and then the shim loads the
values and calls the target function (where the shim and the target have the
same target features enabled). This unfortunately is quite nontrivial to
implement in rustc today (especially when accounting for function pointers and
such).
This commit takes a different solution, *always* passing SIMD arguments through
memory instead of passing as immediates. This strategy solves the problem at the
LLVM layer because the ABI between two functions never uses SIMD registers. This
also shouldn't be a hit to performance because SIMD performance is thought to
often rely on inlining anyway, where a `call` instruction, even if using SIMD
registers, would be disastrous to performance regardless. LLVM should then be
more than capable of fixing all our memory usage to use registers instead after
enough inlining has been performed.
Note that there's a few caveats to this commit though:
* The "platform intrinsic" ABI is omitted from "always pass via memory". This
ABI is used to define intrinsics like `simd_shuffle4` where LLVM and rustc
need to have the arguments as an immediate.
* Additionally this commit does *not* fix the `extern` ("C") ABI. This means
that the bug in #44367 can still happen when using non-Rust-ABI functions. My
hope is that before stabilization we can ban and/or warn about SIMD types in
these functions (as AFAIK there's not much motivation to belong there anyway),
but I'll leave that for a later commit and if this is merged I'll file a
follow-up issue.