This commit is spawned out of a performance regression investigation in #50496.
In tracking down this regression it turned out that the `expand_statements`
function in the compiler was taking quite a long time. Further investigation
showed two key properties:
* The function was "fast" on glibc 2.24 and slow on glibc 2.23
* The hottest function was memmove from glibc
Combined together it looked like glibc gained an optimization to the memmove
function in 2.24. Ideally we don't want to rely on this optimization, so I
wanted to dig further to see what was happening.
The hottest part of `expand_statements` was `Drop for Drain` in the call to
`splice` where we insert new statements into the original vector. This *should*
be a cheap operation because we're draining and replacing iterators of the exact
same length, but under the hood memmove was being called a lot, causing a
slowdown on glibc 2.23.
It turns out that at least one of the optimizations in glibc 2.24 was that
`memmove` where the src/dst are equal becomes much faster. [This program][prog]
executes in ~2.5s against glibc 2.23 and ~0.3s against glibc 2.24, exhibiting
how glibc 2.24 is optimizing `memmove` if the src/dst are equal.
And all that brings us to what this commit itself is doing. The change here is
purely to `Drop for Drain` to avoid the call to `ptr::copy` if the region being
copied doesn't actually need to be copied. For normal usage of just `Drain`
itself this check isn't really necessary, but because `Splice` internally
contains `Drain` this provides a nice speed boost on glibc 2.23. Overall this
should fix the regression seen in #50496 on glibc 2.23 and also fix the
regression on Windows where `memmove` looks to not have this optimization.
Note that the way `splice` was called in `expand_statements` would cause a
quadratic number of elements to be copied via `memmove` which is likely why the
tuple-stress benchmark showed such a severe regression.
Closes#50496
[prog]: https://gist.github.com/alexcrichton/c05bc51c6771bba5ae5b57561a6c1cd3
lint: deny incoherent_fundamental_impls by default
Warn the ecosystem of the pending intent-to-disallow in #49799.
There are 4 ICEs on my machine, look unrelated (having happened before in https://github.com/rust-lang/rust/issues/49146#issuecomment-384473523)
```rust
thread 'main' panicked at 'assertion failed: position <= slice.len()', libserialize/leb128.rs:97:1
```
```
[run-pass] run-pass/allocator/xcrate-use2.rs
[run-pass] run-pass/issue-12133-3.rs
[run-pass] run-pass/issue-32518.rs
[run-pass] run-pass/trait-default-method-xc-2.rs
```
r? @nikomatsakis
idiom lints for removing `extern crate`
Based off of https://github.com/rust-lang/rust/pull/49789
This contains two lints:
- One that suggests replacing pub extern crates with pub use, and removing non-pub extern crates entirely
- One that suggests rewriting `use modulename::...::cratename::foo` as `cratename::foo`
The latter is a bit tricky to emit suggestions for; for one this involves splicing spans (never a good idea), and it also won't be able to correctly
handle `use module::{cratename, foo}` and use-trees. I'm not sure how to proceed here. Currently it doesn't suggest anything at all.
Perhaps we can go the other way and suggest removal of all extern crates _except_ those used through modules (stash node ids somewhere) and suggest replacing those with `<visibility> use`?
r? @nikomatsakis
fixes https://github.com/rust-lang/rust/issues/48719
Use ManuallyDrop instead of Option in BinaryHeap Hole implementation
The Option is always Some until drop, where it becomes None. Make this more explicit and avoid unwraps by using ManuallyDrop.
This change should be performance-neutral as LLVM already optimizes the unwraps away in the inlined code. However I've seen this pattern copied from here to other crates where it is not optimized away, so I think it would be good to change it.
Add some groundwork for cross-language LTO.
Implements part of #49879:
- Adds a `-Z cross-lang-lto` flag to rustc
- Makes sure that bitcode is embedded in object files if the flag is set.
This should already allow for using cross language LTO for staticlibs (where one has to invoke the linker manually anyway). However, `rustc` will not try to enable LTO for its own linker invocations yet.
r? @alexcrichton
Pass a test directory to rustfmt
Another attempt to fix the rustfmt tests. `RUSTFMT_TEST_DIR` is consumed by Rustfmt in the latext commit (thus the Rustfmt update) because we need a place to create temp files that won't be read-only.
r? @alexcrichton
Issue 49938: Reference tagged unions discr(iminant) as tag
Here the changes reference the Tagged type _discriminant_ as _tag_ instead. This is the correct terminology when referencing how tagged unions are represented in memory.
Fix ICE in assertion macro
Fixes#50471. Needs beta-backport (stable-to-beta/nightly regression).
* `panic` with single argument does not need escaping `{` and `}`
* Instead of unescaping `\u{...}` manually, just use `escape_debug` in pprust
The Option is always Some until drop, where it becomes None. Make
this more explicit and avoid unwraps by using ManuallyDrop.
This change should be performance-neutral as LLVM already optimizes
the unwraps away in the inlined code.
rustbuild: Allow quick testing of libstd and libcore at stage0
This PR implemented two features:
1. Added a `--no-doc` flag to allow testing a crate *without* doc tests. In this mode, we don't need to build rustdoc, and thus we can skip building the stage2 compiler. (Ideally stage0 test should use the bootstrap rustdoc, but I don't want to mess up the core builder logic here)
2. Moved all libcore tests externally and added a tidy test to ensure we don't accidentally add `#[test]` into libcore.
After this PR, one could run `./x.py test --stage 0 --no-doc src/libstd` to test `libstd` without building the compiler, thus enables us to quickly test new library features.
proc_macro: Explicitly make everything !Send/Sync
This commit adds explicit imp blocks to ensure that all publicly exported types
(except simple enums) are not `Send` nor `Sync` in the `proc_macro` crate.
cc #38356
Refer https://github.com/rust-lang/rust/issues/49938
Previously tagged unions' tag was refered to as a discr(iminant).
Here the changes use tag instead which is the correct terminology
when refering to the memory representation of tagged unions.
Add a CI job that makes sure rustc builds with parallel queries enabled.
This shouldn't take up too much CI time `:)`
cc https://github.com/rust-lang/rust/issues/48607
cc @Zoxc
r? @alexcrichton
Misc tweaks
This:
- ~~Add explicit dependencies on `getops`~~
- Fixes the libtest-json test when `RUST_BACKTRACE=1` is set
- ~~Sets `opt-level` to `3`~~
- Removes the use of `staged_api` from `rustc_plugin`
- ~~Enables the Windows Error Reporting dialog when running rustc during bootstrapping~~
- Disables Windows Error Reporting dialog when running compiletest tests
- Enables backtraces when running rustc during bootstrapping
- ~~Removes the `librustc` dependency on `libtest`~~
- Triggers JIT debugging on Windows if rustc panics during bootstrapping
r? @alexcrichton
All other tests of libcore reside in the tests/ directory,
too. Apparently the tests of `time.rs` weren't run before, at
least not by `x.py test src/libcore`.
Suggest more helpful formatting string
Based on [user feedback](https://users.rust-lang.org/t/ux-feedback-from-a-rust-newbie/17220) the minimal suggestion of `:?` is unclear.
Also `{:#?}` is much more readable than the standard debug, so this PR suggests it to help surface this nice feature.