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%.
cc #33111
mir: drop temps outside-in by scheduling the drops inside-out.
It was backwards all along, but only noticeable with multiple drops in one rvalue scope. Fixes#32433.
Split the type context into a global and a local (inference-only) one.
After this change, each `InferCtxt` creates its own local type interner for types with inference by-products.
Most of the code which handles both a global and a local interner uses `'gcx` and `'tcx` for them.
A reference to the type context in that situation (e.g. `infcx.tcx`) is `TyCtxt<'a, 'gcx, 'tcx>`.
The global type context which used to be `&'a TyCtxt<'tcx>` is now `TyCtxt<'a, 'tcx, 'tcx>`.
In order to minimize the number of extra lifetime parameters, many functions became methods.
Where possible (some inherent impls), lifetime parameters were added on the impl, not each method.
As inference by-products no longer escape their inference contexts, memory usage is lower.
Example of `-Z time-passes` excerpt for `librustc`, stage1 (~100MB gains):
Before "rustc: Split local type contexts interners from the global one.":
```
time: 0.395; rss: 335MB item-types checking
time: 15.392; rss: 472MB item-bodies checking
time: 0.000; rss: 472MB drop-impl checking
time: 1.140; rss: 478MB const checking
time: 0.139; rss: 478MB privacy checking
time: 0.024; rss: 478MB stability index
time: 0.072; rss: 478MB intrinsic checking
time: 0.038; rss: 478MB effect checking
time: 0.255; rss: 478MB match checking
time: 0.128; rss: 484MB liveness checking
time: 1.372; rss: 484MB rvalue checking
time: 1.404; rss: 597MB MIR dump
time: 0.809; rss: 599MB MIR passes
```
After:
```
time: 0.467; rss: 337MB item-types checking
time: 17.443; rss: 395MB item-bodies checking
time: 0.000; rss: 395MB drop-impl checking
time: 1.423; rss: 401MB const checking
time: 0.141; rss: 401MB privacy checking
time: 0.024; rss: 401MB stability index
time: 0.116; rss: 401MB intrinsic checking
time: 0.038; rss: 401MB effect checking
time: 0.382; rss: 401MB match checking
time: 0.132; rss: 407MB liveness checking
time: 1.678; rss: 407MB rvalue checking
time: 1.614; rss: 503MB MIR dump
time: 0.957; rss: 512MB MIR passes
```
**NOTE**: Functions changed to methods weren't re-indented to keep this PR easier to review.
Once approved, the changes will be mechanically performed.
However, indentation changes of function arguments are there - and I believe there's a way to hide whitespace-only changes in diffs on GitHub.
rustdoc: remove artificial indentation of doctest code
The indentation makes the examples look nicer when printed (when is this done?), but breaks tests using multi-line string literals.
Fixes: #25944
borrowck: do not suggest to change "&mut self" to "&mut mut self"
Matching the snippet string might not be the cleanest, but matching
the AST node instead seems to end in a lot of nested `if let`s, so I
don't know what's better.
Of course it's entirely possible that there is another API altogether
that I just don't know of?
Fixes#31424.
resolve: do not modify span of non-importable name
This span modification is probably leftover from a time when import spans were assigned differently.
With this change, error spans for the following are properly reported:
```
use abc::one_el;
use abc::{a, bbb, cccccc};
use a_very_long_name::{el, el2};
```
before (spans only):
```
x.rs:3 use abc::one_el;
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
(internal compiler error: unprintable span)
(internal compiler error: unprintable span)
```
after:
```
x.rs:3 use abc::one_el;
^~~~~~~~~~~
x.rs:4 use abc::{a, bbb, cccccc};
^
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~~~~
x.rs:5 use a_very_long_name::{el, el2};
^~
x.rs:5 use a_very_long_name::{el, el2};
^~~
```
Fixes: #33464
Preparatory refactorings for collector-driven trans.
This is a set of refactorings that allows to do translation item collection and partitioning before LocalCrateContext instances or LLVM modules are generated. As a consequence we can now create LocalCrateContexts already with knowledge of the codegen unit it will be used for. This is a preparation step for driving trans by the results of codegen unit partitioning.
This span modification is probably leftover from a time when
import spans were assigned differently.
With this change, error spans for the following are properly reported:
```
use abc::one_el;
use abc::{a, bbb, cccccc};
use a_very_long_name::{el, el2};
```
before (spans only):
```
x.rs:3 use abc::one_el;
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~
(internal compiler error: unprintable span)
(internal compiler error: unprintable span)
```
after:
```
x.rs:3 use abc::one_el;
^~~~~~~~~~~
x.rs:4 use abc::{a, bbb, cccccc};
^
x.rs:4 use abc::{a, bbb, cccccc};
^~~
x.rs:4 use abc::{a, bbb, cccccc};
^~~~~~
x.rs:5 use a_very_long_name::{el, el2};
^~
x.rs:5 use a_very_long_name::{el, el2};
^~~
```
Fixes: #33464
Perform name resolution before and during ast->hir lowering
This PR performs name resolution before and during ast->hir lowering instead of in phase 3.
r? @nrc
rustc: Implement custom panic runtimes
This commit is an implementation of [RFC 1513] which allows applications to
alter the behavior of panics at compile time. A new compiler flag, `-C panic`,
is added and accepts the values `unwind` or `panic`, with the default being
`unwind`. This model affects how code is generated for the local crate, skipping
generation of landing pads with `-C panic=abort`.
[RFC 1513]: https://github.com/rust-lang/rfcs/blob/master/text/1513-less-unwinding.md
Panic implementations are then provided by crates tagged with
`#![panic_runtime]` and lazily required by crates with
`#![needs_panic_runtime]`. The panic strategy (`-C panic` value) of the panic
runtime must match the final product, and if the panic strategy is not `abort`
then the entire DAG must have the same panic strategy.
With the `-C panic=abort` strategy, users can expect a stable method to disable
generation of landing pads, improving optimization in niche scenarios,
decreasing compile time, and decreasing output binary size. With the `-C
panic=unwind` strategy users can expect the existing ability to isolate failure
in Rust code from the outside world.
Organizationally, this commit dismantles the `sys_common::unwind` module in
favor of some bits moving part of it to `libpanic_unwind` and the rest into the
`panicking` module in libstd. The custom panic runtime support is pretty similar
to the custom allocator support with the only major difference being how the
panic runtime is injected (takes the `-C panic` flag into account).
Closes#32837
Currently the compiler has two relatively critical bugs in the implementation of
MSVC unwinding:
* #33112 - faults like segfaults and illegal instructions will run destructors
in Rust, meaning we keep running code after a super-fatal exception
has happened.
* #33116 - When compiling with LTO plus `-Z no-landing-pads` (or `-C
panic=abort` with the previous commit) LLVM won't remove all `invoke`
instructions, meaning that some landing pads stick around and
cleanups may be run due to the previous bug.
These both stem from the flavor of "personality function" that Rust uses for
unwinding on MSVC. On 32-bit this is `_except_handler3` and on 64-bit this is
`__C_specific_handler`, but they both essentially are the "most generic"
personality functions for catching exceptions and running cleanups. That is,
thse two personalities will run cleanups for all exceptions unconditionally, so
when we use them we run cleanups for **all SEH exceptions** (include things like
segfaults).
Note that this also explains why LLVM won't optimize away `invoke` instructions.
These functions can legitimately still unwind (the `nounwind` attribute only
seems to apply to "C++ exception-like unwining"). Also note that the standard
library only *catches* Rust exceptions, not others like segfaults and illegal
instructions.
LLVM has support for another personality, `__CxxFrameHandler3`, which does not
run cleanups for general exceptions, only C++ exceptions thrown by
`_CxxThrowException`. This essentially ideally matches our use case, so this
commit moves us over to using this well-known personality function as well as
exception-throwing function.
This doesn't *seem* to pull in any extra runtime dependencies just yet, but if
it does we can perhaps try to work out how to implement more of it in Rust
rather than relying on MSVCRT runtime bits.
More details about how this is actually implemented can be found in the changes
itself, but this...
Closes#33112Closes#33116
rustdoc: do not strip blanket impls in crate of origin
In `impl<T> Trait for T`, the blanket type parameters `T` were recognized as "local" and "not exported", so these impls were thrown out.
Now we check if they are generic, and keep them in that case.
Fixes: #29503
book: fixup code in error handling tutorial
A few oversights happened while porting the example from docopt to getopts. I retraced all the steps, fixing code and description as necessary.
Fixes: #33422
save-analysis: use a decoupled representation for dumped data
Closes#33348
This will probably break any tool relying on the csv backend of save_analysis, for the following reasons:
1. Dumped spans don't contain extents anymore (`Dump` uses `SpanData` now instead of internal `Span`s). In case we still want to dump extents we could add them to `SpanData`.
1. `DefId`s are no longer dumped as a pair of `(ref_id, ref_crate)`. Instead, they are dumped as a single `Id`.
@nrc You said something about storing the id in a `u64`, but you didn't explain why. I kept using `u32` in this branch but I can change it if you prefer that.
r? @nrc
By the way, the fact that this breaks tools relying on CSV may be a good occasion to start dumping CSV in a different way (i.e. using the serializer like in the JSON backend).
std: Allow creating ExitStatus from raw values
Sometimes a process may be waited on externally from the standard library, in
which case it can be useful to create a raw `ExitStatus` structure to return.
This commit extends the existing Unix `ExitStatusExt` extension trait and adds a
new Windows-specific `ExitStatusExt` extension trait to do this. The methods are
currently called `ExitStatus::from_raw`.
cc #32713
std: Allow creating ExitStatus from raw values
Sometimes a process may be waited on externally from the standard library, in
which case it can be useful to create a raw `ExitStatus` structure to return.
This commit extends the existing Unix `ExitStatusExt` extension trait and adds a
new Windows-specific `ExitStatusExt` extension trait to do this. The methods are
currently called `ExitStatus::from_raw`.
cc #32713