Adjust the handling of `#[inline]` items so that they get translated into every
compilation unit that uses them. This is necessary to preserve the semantics
of `#[inline(always)]`.
Crate-local `#[inline]` functions and statics are blindly translated into every
compilation unit. Cross-crate inlined items and monomorphizations of
`#[inline]` functions are translated the first time a reference is seen in each
compilation unit. When using multiple compilation units, inlined items are
given `available_externally` linkage whenever possible to avoid duplicating
object code.
Add a post-processing pass to `trans` that converts symbols from external to
internal when possible. Translation with multiple compilation units initially
makes most symbols external, since it is not clear when translating a
definition whether that symbol will need to be accessed from another
compilation unit. This final pass internalizes symbols that are not reachable
from other crates and not referenced from other compilation units, so that LLVM
can perform more aggressive optimizations on those symbols.
Use a shared lookup table of previously-translated monomorphizations/glue
functions to avoid translating those functions in every compilation unit where
they're used. Instead, the function will be translated in whichever
compilation unit uses it first, and the remaining compilation units will link
against that original definition.
Rotate between compilation units while translating. The "worker threads"
commit added support for multiple compilation units, but only translated into
one, leaving the rest empty. With this commit, `trans` rotates between various
compilation units while translating, using a simple stragtegy: upon entering a
module, switch to translating into whichever compilation unit currently
contains the fewest LLVM instructions.
Most of the actual changes here involve getting symbol linkage right, so that
items translated into different compilation units will link together properly
at the end.
When inlining an item from another crate, use the original symbol from that
crate's metadata instead of generating a new symbol using the `ast::NodeId` of
the inlined copy. This requires exporting symbols in the crate metadata in a
few additional cases. Having predictable symbols for inlined items will be
useful later to avoid generating duplicate object code for inlined items.
Refactor the code in `llvm::back` that invokes LLVM optimization and codegen
passes so that it can be called from worker threads. (Previously, it used
`&Session` extensively, and `Session` is not `Share`.) The new code can handle
multiple compilation units, by compiling each unit to `crate.0.o`, `crate.1.o`,
etc., and linking together all the `crate.N.o` files into a single `crate.o`
using `ld -r`. The later linking steps can then be run unchanged.
The new code preserves the behavior of `--emit`/`-o` when building a single
compilation unit. With multiple compilation units, the `--emit=asm/ir/bc`
options produce multiple files, so combinations like `--emit=ir -o foo.ll` will
not actually produce `foo.ll` (they instead produce several `foo.N.ll` files).
The new code supports `-Z lto` only when using a single compilation unit.
Compiling with multiple compilation units and `-Z lto` will produce an error.
(I can't think of any good reason to do such a thing.) Linking with `-Z lto`
against a library that was built as multiple compilation units will also fail,
because the rlib does not contain a `crate.bytecode.deflate` file. This could
be supported in the future by linking together the `crate.N.bc` files produced
when compiling the library into a single `crate.bc`, or by making the LTO code
support multiple `crate.N.bytecode.deflate` files.
Break up `CrateContext` into `SharedCrateContext` and `LocalCrateContext`. The
local piece corresponds to a single compilation unit, and contains all
LLVM-related components. (LLVM data structures are tied to a specific
`LLVMContext`, and we will need separate `LLVMContext`s to safely run
multithreaded optimization.) The shared piece contains data structures that
need to be shared across all compilation units, such as the `ty::ctxt` and some
tables related to crate metadata.
Use '^' to specify center alignment in format strings.
```
fmt!( "[{:^5s}]", "Hi" ) -> "[ Hi ]"
fmt!( "[{:^5s}]", "H" ) -> "[ H ]"
fmt!( "[{:^5d}]", 1i ) -> "[ 1 ]"
fmt!( "[{:^5d}]", -1i ) -> "[ -1 ]"
fmt!( "[{:^6d}]", 1i ) -> "[ 1 ]"
fmt!( "[{:^6d}]", -1i ) -> "[ -1 ]"
```
If the padding is odd then the padding on the right will be one
character longer than the padding on the left.
Use '^' to specify center alignment in format strings.
fmt!( "[{:^5s}]", "Hi" ) -> "[ Hi ]"
fmt!( "[{:^5s}]", "H" ) -> "[ H ]"
fmt!( "[{:^5d}]", 1i ) -> "[ 1 ]"
fmt!( "[{:^5d}]", -1i ) -> "[ -1 ]"
fmt!( "[{:^6d}]", 1i ) -> "[ 1 ]"
fmt!( "[{:^6d}]", -1i ) -> "[ -1 ]"
If the padding is odd then the padding on the right will be one
character longer than the padding on the left.
Tuples squashed
They were only correct in the simplest case. Some of the optimisations
are certainly possible but should be introduced carefully and only
when the whole pattern codegen infrastructure is in a better shape.
Fixes#16648.
This has the primary advantage of not interfering with browser default behavior for links like being able to cmd/ctrl+click on a result to open the result in a new tab but leave the current page as-is (previous behavior both opened a new tab and changed the current tab's location to the result's).
I've done my best to keep the rest of the behavior and the appearance the same-- the whole row still highlights, still has a hand cursor, still moves to the result page with a normal click, arrows+enter still work. If the result is on the current page, the search is simply hidden.
The biggest difference in behavior is that people using tab to navigate through the links will have to hit tab twice for each row, since each cell has its own `a` tag.. I could fix this by switching to `div`s and `span`s instead of a table, but that's potentially more CSS finicky?
The biggest difference in appearance is probably that all the text in the search results is Fira Sans now, instead of just the method name with the rest of the text in Source Serif Pro. I can put this appearance back, but it looks like all links anywhere on the page are Fira Sans. Only the name was in an `a` tag before, but the whole row was ACTING like a link, so I think this is actually more consistent.
[I've pushed these changes to a gh-pages repo](https://carols10cents.github.io/rustdoc-playground/std/index.html?search=t) if you'd like to take a look at the effects; note that I also have my changes for PR #16735 there too so the search results will be sorted differently than on master.
bitv: add larger tests, better benchmarks & remove dead code.
There were no tests for iteration etc. with more than 5 elements,
i.e. not even going beyond a single word. This situation is rectified.
Also, the only benchmarks for `set` were with a constant bit value,
which was not indicative of every situation, due to inlining & branch
removal. This adds a benchmark at the other end of the spectrum: random
input.
closes#16800
r? @nikomatsakis - I'm not 100% sure this is the right approach, it is kind of ad-hoc. The trouble is we don't have any intrinsic notion of which types are sized and which are not, we only have the Sized bound, so I have nothing to validate the Sized bound against.
As outlined in
https://aturon.github.io/style/naming/conversions.html
`to_` functions names should only be used for expensive operations.
Thus `to_option` is better named `as_option`. Also, putting type
names into method names is considered bad style; what the user is
really trying to get is a reference. This `as_ref` is even better.
Also, we are missing a mutable version of this method.
Finally, there is a bug in the signature of `to_option` which has
been around since lifetime elision: originally the returned reference
had 'static lifetime, but since the elision changes this become
the lifetime of the raw pointer (which does not make sense, since
the pointer lifetime and referent lifetime are unrelated). We fix
the bug to return a reference with a fresh lifetime which will be
inferred from the calling context.
[breaking-change]
There were no tests for iteration etc. with more than 5 elements,
i.e. not even going beyond a single word. This situation is rectified.
Also, the only benchmarks for `set` were with a constant bit value,
which was not indicative of every situation, due to inlining & branch
removal. This adds a benchmark at the other end of the spectrum: random
input.
Fixes#16597
I'm not 100% sure this is the correct way to handle this - but I wasn't able to find a better way without doing way more refactoring of the code that I was comfortable with. Comments and criticism are appreciated 😄