[MIR] SwitchInt Everywhere
Something I've been meaning to do for a very long while. This PR essentially gets rid of 3 kinds of conditional branching and only keeps the most general one - `SwitchInt`. Primary benefits are such that dealing with MIR now does not involve dealing with 3 different ways to do conditional control flow. On the other hand, constructing a `SwitchInt` currently requires more code than what previously was necessary to build an equivalent `If` terminator. Something trivially "fixable" with some constructor methods somewhere (MIR needs stuff like that badly in general).
Some timings (tl;dr: slightly faster^1 (unexpected), but also uses slightly more memory at peak (expected)):
^1: Not sure if the speed benefits are because of LLVM liking the generated code better or the compiler itself getting compiled better. Either way, its a net benefit. The CORE and SYNTAX timings done for compilation without optimisation.
```
AFTER:
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Finished release [optimized] target(s) in 31.50 secs
Finished release [optimized] target(s) in 31.42 secs
Building stage1 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Finished release [optimized] target(s) in 439.56 secs
Finished release [optimized] target(s) in 435.15 secs
CORE: 99% (24.81 real, 0.13 kernel, 24.57 user); 358536k resident
CORE: 99% (24.56 real, 0.15 kernel, 24.36 user); 359168k resident
SYNTAX: 99% (49.98 real, 0.48 kernel, 49.42 user); 653416k resident
SYNTAX: 99% (50.07 real, 0.58 kernel, 49.43 user); 653604k resident
BEFORE:
Building stage1 std artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Finished release [optimized] target(s) in 31.84 secs
Building stage1 compiler artifacts (x86_64-unknown-linux-gnu -> x86_64-unknown-linux-gnu)
Finished release [optimized] target(s) in 451.17 secs
CORE: 99% (24.66 real, 0.20 kernel, 24.38 user); 351096k resident
CORE: 99% (24.36 real, 0.17 kernel, 24.18 user); 352284k resident
SYNTAX: 99% (52.24 real, 0.56 kernel, 51.66 user); 645544k resident
SYNTAX: 99% (51.55 real, 0.48 kernel, 50.99 user); 646428k resident
```
cc @nikomatsakis @eddyb
macros: fix inert attributes from `proc_macro_derives` with `#![feature(proc_macro)]`
This PR refactors collection of `proc_macro_derive` invocations to fix#39347.
After this PR, the input to a `#[proc_macro_derive]` function no longer sees `#[derive]`s on the underlying item. For example, consider:
```rust
extern crate my_derives;
use my_derives::{Trait, Trait2};
#[derive(Copy, Clone)]
#[derive(Trait)]
#[derive(Trait2)]
struct S;
```
Today, the input to the `Trait` derive is `#[derive(Copy, Clone, Trait2)] struct S;`, and the input to the `Trait2` derive is `#[derive(Copy, Clone)] struct S;`. More generally, a `proc_macro_derive` sees all builtin derives, as well as all `proc_macro_derive`s listed *after* the one being invoked.
After this PR, both `Trait` and `Trait2` will see `struct S;`.
This is a [breaking-change], but I believe it is highly unlikely to cause breakage in practice.
r? @nrc
rustdoc: Show attributes on all item types
Currently attributes are only shown for structs, unions and enums but
they should be shown for all items. For example it is useful to know if a
function is `#[no_mangle]`.
improve error message when two-arg assert_eq! receives a trailing comma
Previously, `assert_eq!(left, right,)` (respectively, `assert_ne!(left,
right,)`; note the trailing comma) would result in a confusing "requires
at least a format string argument" error. In reality, a format string is
optional, but the trailing comma puts us into the "match a token tree of
zero or more tokens" branch of the macro (in order to support the
optional format string), and passing the empty token tree into
`format_args!` results in the confusing error. If instead we match a
token tree of one or more tokens, we get a much more sensible
"unexpected end of macro invocation" error.
While we're here, fix up a stray space before a comma in the match
guards.
Resolves#39369.
-----
**Before:**
```
$ rustc scratch.rs
error: requires at least a format string argument
--> scratch.rs:2:5
|
2 | assert_eq!(1, 2,);
| ^^^^^^^^^^^^^^^^^^
|
= note: this error originates in a macro outside of the current crate
error: aborting due to previous error
```
**After:**
```
$ ./build/x86_64-unknown-linux-gnu/stage1/bin/rustc scratch.rs
error: unexpected end of macro invocation
--> scratch.rs:2:20
|
2 | assert_eq!(1, 2,);
| ^
```
treat setting the number of test-threads to 0 as an error
It is currently possible to call `cargo test -- --test-threads=0` which will cause cargo to hang until aborted. This change will fix that and will report an appropriate error to the user.
[LLVM 4.0] Fix CreateCompileUnit
This is largely identical to @dylanmckay's [patch](https://github.com/dylanmckay), except that it doesn't try to use `file_metadata()`. I don't think that is necessary because we don't want the compile unit to be added to `debug_context.created_files`, though I'd like confirmation from someone who knows for sure. If that is needed, I can modify `file_metadata_()` so that it can be used from `compile_unit_metadata()`.
Allow rustc data structures compile to android
flock structure is defined in asm*/fcntl.h. This file on android is
generated from the linux kernel source, so they are the same.
Explicitly mention that `Vec::reserve` is based on len not capacity
I spent a good chunk of time tracking down a buffer overrun bug that
resulted from me mistakenly thinking that `reserve` was based on the
current capacity not the current length. It would be helpful if this
were called out explicitly in the docs.
remove wrong packed struct test
This UB was found by running the test under [Miri](https://github.com/solson/miri) which rejects these unsafe unaligned loads. 😄
Actually fix manifest generation
The previous fix contained an error where `toml::encode` returned a runtime
error, so this version just constructs a literal `toml::Value`.
Don't include directory names in shasums
Right now we just run `shasum` on an absolute path but right now the shasum
files only include filenames, so let's use `current_dir` and just the file name
to only have the file name emitted.
Fix a misleading statement in `Iterator.nth()`
The `Iterator.nth()` documentation says "Note that all preceding elements will be consumed". I assumed from that that the preceding elements would be the *only* ones that were consumed, but in fact the returned element is consumed as well.
The way I read the documentation, I assumed that `nth(0)` would not discard anything (there are 0 preceding elements, and maybe it just peeks at the start of the iterator somehow), so I added a sentence clarifying that it does. I also rephrased it to avoid the stunted "i.e." phrasing.
Specialize `PartialOrd<A> for [A] where A: Ord`
This way we can call `cmp` instead of `partial_cmp` in the loop, removing some burden of optimizing `Option`s away from the compiler.
PR #39538 introduced a regression where sorting slices suddenly became slower, since `slice1.lt(slice2)` was much slower than `slice1.cmp(slice2) == Less`. This problem is now fixed.
To verify, I benchmarked this simple program:
```rust
fn main() {
let mut v = (0..2_000_000).map(|x| x * x * x * 18913515181).map(|x| vec![x, x ^ 3137831591]).collect::<Vec<_>>();
v.sort();
}
```
Before this PR, it would take 0.95 sec, and now it takes 0.58 sec.
I also tried changing the `is_less` lambda to use `cmp` and `partial_cmp`. Now all three versions (`lt`, `cmp`, `partial_cmp`) are equally performant for sorting slices - all of them take 0.58 sec on the
benchmark.
Tangentially, as soon as we get `default impl`, it might be a good idea to implement a blanket default impl for `lt`, `gt`, `le`, `ge` in terms of `cmp` whenever possible. Today, those four functions by default are only implemented in terms of `partial_cmp`.
r? @alexcrichton
Add Emscripten-specific linker
Emscripten claims to accept most GNU linker options, but in fact most of `-Wl,...` are useless for it and instead it requires some additional special options which are easier to handle in a separate trait.
Currently added:
- `export_symbols`: works on executables as special Emscripten case since staticlibs/dylibs aren't compiled to JS, while exports are required to be accessible from JS.
Fixes#39171.
- `optimize` - translates Rust's optimization level to Emscripten optimization level (whether passed via `-C opt-level=...` or `-O...`).
Fixes#36899.
- `debuginfo` - translates debug info; Emscripten has 5 debug levels while Rust has 3, so chose to translate `-C debuginfo=1` to `-g3` (preserves whitespace, variable and function names for easy debugging).
Fixes#36901.
- `no_default_libraries` - tells Emscripten to exclude `memcpy` and co.
TODO (in future PR): dynamic linking via `SIDE_MODULE` / `MAIN_MODULE` mechanism.
Conversions between slices and boxes
This allows conversion for `Copy` slices, `str`, and `CStr` into their boxed counterparts.
This also adds the method `CString::into_boxed_c_str`.
I would like to add similar implementations for `OsStr` as well, but I have not figured out how.