Move `DepKind` to `rustc_query_system` and define it as `u16`
This moves the `DepKind` type to `rustc_query_system` where it's defined with an inner `u16` field. This decouples it from `rustc_middle` and is a step towards letting other crates define dep kinds. It also allows some type parameters to be removed. The `DepKind` trait is replaced with a `Deps` trait. That's used when some operations or information about dep kinds which is unavailable in `rustc_query_system` are still needed.
r? `@cjgillot`
Simplify/Optimize FileEncoder
FileEncoder is basically a BufWriter except that it exposes access to the not-written-to-yet region of the buffer so that some users can write directly to the buffer. This strategy is awesome because it lets us avoid calling memcpy for small copies, but the previous strategy was based on the writer accessing a `&mut [MaybeUninit<u8>; N]` and returning a `&[u8]` which is an API which currently mandates the use of unsafe code, making that interface in general not that appealing.
So this PR cleans up the FileEncoder implementation and builds on that general idea of direct buffer access in order to prevent `memcpy` calls in a few key places when encoding the dep graph and rmeta tables. The interface used here is now 100% safe, but with the caveat that internally we need to avoid trusting the number of bytes that the provided function claims to have written.
The original primary objective of this PR was to clean up the FileEncoder implementation so that the fix for the following issues would be easy to implement. The fix for these issues is to correctly update self.buffered even when writes fail, which I think it's easy to verify manually is now done, because all the FileEncoder methods are small.
Fixes https://github.com/rust-lang/rust/issues/115298
Fixes https://github.com/rust-lang/rust/issues/114671
Fixes https://github.com/rust-lang/rust/issues/114045
Fixes https://github.com/rust-lang/rust/issues/108100
Fixes https://github.com/rust-lang/rust/issues/106787
Make `.rmeta` file in `dep-info` have correct name (`lib` prefix)
Since `filename_for_metadata()` and
`OutputFilenames::path(OutputType::Metadata)` had different logic for the name of the metadata file, the `.d` file contained a file name different from the actual name used. Share the logic to fix the out-of-sync name.
Without this fix, the `.d` file contained
dash-separated_something-extra.rmeta: dash-separated.rs
instead of
libdash_separated_something-extra.rmeta: dash-separated.rs
which is the name of the file that is actually written by the compiler.
Worth noting: It took me several iterations to get all tests to pass, so I am relatively confident that this PR does not break anything.
Closes#68839
Encode only MIR reachable from other crates
Only reachable items might participate in the code generation in the
downstream crates. Omit redundant optimized MIR of unreachable items
from a crate metadata.
Additionally, include reachable closures in reachable set, so that
unreachable closures can be omitted on the same basis.
Only reachable items might participate in the code generation in the
downstream crates. Omit redundant optimized MIR of unreachable items
from a crate metadata.
Additionally, include reachable closures in reachable set, so that
unreachable closures can be omitted on the same basis.
Since `filename_for_metadata()` and
`OutputFilenames::path(OutputType::Metadata)` had different logic for
the name of the metadata file, the `.d` file contained a file name
different from the actual name used. Share the logic to fix the
out-of-sync name.
Closes 68839.
Skip rendering metadata strings from include_str!/include_bytes!
The const rendering code in rustdoc completely ignores consts from expansions, but the compiler was rendering all consts. So some consts (namely those from `include_bytes!`) were rendered then ignored.
Most of the diff here is from moving `print_const_expr` from rustdoc into `rustc_hir_pretty` so that it can be used in rustdoc and when building rmeta files.
Adapt table sizes to the contents
This is an implementation of https://github.com/rust-lang/compiler-team/issues/666
The objective of this PR is to permit the rmeta format to accommodate larger crates that need offsets larger than a `u32` can store without compromising performance for crates that do not need such range. The second commit is a number of tiny optimization opportunities I noticed while looking at perf recordings of the first commit.
The rmeta tables need to have fixed-size elements to permit lazy random access. But the size only needs to be fixed _per table_, not per element type. This PR adds another `usize` to the table header which indicates the table element size. As each element of a table is set, we keep track of the widest encoded table value, then don't bother encoding all the unused trailing bytes on each value. When decoding table elements, we copy them to a full-width array if they are not already full-width.
`LazyArray` needs some special treatment. Most other values that are encoded in tables are indexes or offsets, and those tend to be small so we get to drop a lot of zero bytes off the end. But `LazyArray` encodes _two_ small values in a fixed-width table element: A position of the table and the length of the table. The treatment described above could trim zero bytes off the table length, but any nonzero length shields the position bytes from the optimization. To improve this, we interleave the bytes of position and length. This change is responsible for about half of the crate metadata win on many crates.
Fixes https://github.com/rust-lang/rust/issues/112934 (probably)
Fixes https://github.com/rust-lang/rust/issues/103607
rustc_interface: Dismantle `register_plugins` query
It did three independent things:
- Constructed `LintStore`
- Prepared incremental directories and dep graph
- Initialized some fields in `Session`
The `LintStore` construction (now `passes::create_lint_store`) is more or less left in place.
The incremental stuff is now moved into `fn dep_graph_future`.
This helps us to start loading the dep graph a bit earlier.
The `Session` field initialization is moved to tcx construction point.
Now that tcx is constructed early these fields don't even need to live in `Session`, they can live in tcx instead and be initialized at its creation (see the FIXME).
Three previously existing `rustc_interface` queries are de-querified (`register_plugins`, `dep_graph_future`, `dep_graph`) because they are only used locally in `fn global_ctxt` and their results don't need to be saved elsewhere.
On the other hand, `crate_types` and `stable_crate_id` are querified.
They are used from different places and their use is very similar to the existing `crate_name` query in this regard.
Suggest `x build library` for a custom toolchain that fails to load `core`
Fixes#113222
The nicer suggestion for dev-channel won't be emitted if `-Z ui-testing` enabled. IMO, this is acceptable for now.
Don't install default projection bound for return-position `impl Trait` in trait methods with no body
This ensures that we never try to project to an opaque type in a trait method that has no body to infer its hidden type, which means we never later call `type_of` on that opaque. This is because opaque types try to reveal their hidden type when proving auto traits.
I thought about this a lot, and I think this is a fix that's less likely to introduce other strange downstream ICEs than #113461.
Fixes#113434
r? `@spastorino`
fix intra-doc links on nested `use` and `extern crate` items
This PR fixes two rustdoc ICEs that happen if there are any intra-doc links on nested `use` or `extern crate` items, for example:
```rust
/// Re-export [`fmt`] and [`io`].
pub use std::{fmt, io}; // "nested" use = use with braces
/// Re-export [`std`].
pub extern crate std;
```
Nested use items were incorrectly considered private and therefore didn't have their intra-doc links resolved. I fixed this by always resolving intra-doc links for nested `use` items that are declared `pub`.
<details>
During AST->HIR lowering, nested `use` items are desugared like this:
```rust
pub use std::{}; // "list stem"
pub use std::fmt;
pub use std::io;
```
Each of these HIR nodes has it's own effective visibility and the list stem is always considered private.
To check the effective visibility of an AST node, the AST node is mapped to a HIR node with `Resolver::local_def_id`, which returns the (private) list stem for nested use items.
</details>
For `extern crate`, there was a hack in rustdoc that stored the `DefId` of the crate itself in the cleaned item, instead of the `DefId` of the `extern crate` item. This made rustdoc look at the resolved links of the extern crate's crate root instead of the `extern crate` item. I've removed this hack and instead translate the `DefId` in the appropriate places.
As as side effect of fixing `extern crate`, i've turned
```rust
#[doc(masked)]
extern crate self as _;
```
into a no-op instead of hiding all trait impls. Proper verification for `doc(masked)` is included as a bonus.
fixes https://github.com/rust-lang/rust/issues/113896