Replace the spdx-rs dependency with a minimal in-tree SPDX tag-value parser
The spdx-rs crate [is no longer maintained](https://github.com/doubleopen-project/spdx-rs/pulls) and is behind on its own dependency updates. It is currently used in [the collect-license-metadata tool](https://github.com/rust-lang/rust/tree/main/src/tools/collect-license-metadata), employing a single function therefrom: `spdx_rs::parsers::spdx_from_tag_value`, which parses the output of the `reuse` tool to extract file names, licences and copyright text.
This PR replaces the use of said function with a small minimal parser that handles just the subset of the SPDX tag-value format that is needed: `Tag: Value` line pairs and multi-line `<text>...</text>` blocks.
Coincidentally, this gets rid of the last transitive dependency on syn v1.
Refactor FnDecl and FnSig non-type fields into a new wrapper type
#### Why this Refactor?
This PR is part of an initial cleanup for the [arg splat experiment](https://github.com/rust-lang/rust/issues/153629), but it's a useful refactor by itself.
It refactors the non-type fields of `FnDecl`, `FnSig`, and `FnHeader` into a new packed wrapper types, based on this comment in the `splat` experiment PR:
https://github.com/rust-lang/rust/pull/153697#discussion_r3004637413
It also refactors some common `FnSig` creation settings into their own methods. I did this instead of creating a struct with defaults.
#### Relationship to `splat` Experiment
I don't think we can use functional struct updates (`..default()`) to create `FnDecl` and `FnSig`, because we need the bit-packing for the `splat` experiment.
Bit-packing will avoid breaking "type is small" assertions for commonly used types when `splat` is added.
This PR packs these types:
- ExternAbi: enum + `unwind` variants (38) -> 6 bits
- ImplicitSelfKind: enum variants (5) -> 3 bits
- lifetime_elision_allowed, safety, c_variadic: bool -> 1 bit
#### Minor Changes
Fixes some typos, and applies rustfmt to clippy files that got skipped somehow.
Set up API to make it possible to pass closures instead of `AttributeLint`
Part of https://github.com/rust-lang/rust/issues/153099.
This PR sets up the base implementations needed to remove `AttributeLintKind` entirely and migrate two variants as examples.
r? @JonathanBrouwer
compiler: update hashbrown to 0.17
See library's rust-lang/rust#155154 for the bug fixes this brings.
This PR also updates `indexmap` in the compiler as a direct dependent.
The spdx-rs crate is no longer maintained and is behind on its own dependency
updates. The only function that collect-license-metadata uses from it is
`spdx_rs::parsers::spdx_from_tag_value`, which parses the output of the `reuse`
tool to extract file names, licences and copyright text.
Replace this with a small minimal parser that handles just the subset
of the SPDX tag-value format that is needed: `Tag: Value` line pairs
and multi-line `<text>...</text>` blocks.
Coincidentally, this gets rid of the last transitive dependency on syn v1.
Rollup of 6 pull requests
Successful merges:
- rust-lang/rust#152901 (Introduce a `#[diagnostic::on_unknown]` attribute)
- rust-lang/rust#155078 (Reject dangling attributes in where clauses)
- rust-lang/rust#154449 (Invert dependency between `rustc_errors` and `rustc_abi`.)
- rust-lang/rust#154646 (Add suggestion to `.to_owned()` used on `Cow` when borrowing)
- rust-lang/rust#154993 (compiletest: pass -Zunstable-options for unpretty and no-codegen paths)
- rust-lang/rust#155097 (Make `rustc_attr_parsing::SharedContext::emit_lint` take a `MultiSpan` instead of a `Span`)
Invert dependency between `rustc_errors` and `rustc_abi`.
Currently, `rustc_errors` depends on `rustc_abi`, which depends on `rustc_error_messages`. This is a bit odd.
`rustc_errors` depends on `rustc_abi` for a single reason: `rustc_abi` defines a type `TargetDataLayoutErrors` and `rustc_errors` impls `Diagnostic` for that type.
We can get a more natural relationship by inverting the dependency, moving the `Diagnostic` trait upstream. Then `rustc_abi` defines `TargetDataLayoutErrors` and also impls `Diagnostic` for it. `rustc_errors` is already pretty far upstream in the crate graph, it doesn't hurt to push it a little further because errors are a very low-level concept.
r? @davidtwco
Currently, `rustc_errors` depends on `rustc_abi`, which depends on
`rustc_error_messages`. This is a bit odd.
`rustc_errors` depends on `rustc_abi` for a single reason: `rustc_abi`
defines a type `TargetDataLayoutErrors` and `rustc_errors` impls
`Diagnostic` for that type.
We can get a more natural relationship by inverting the dependency,
moving the `Diagnostic` trait upstream. Then `rustc_abi` defines
`TargetDataLayoutErrors` and also impls `Diagnostic` for it.
`rustc_errors` is already pretty far upstream in the crate graph, it
doesn't hurt to push it a little further because errors are a very
low-level concept.
Revert "Unstable book options parser"
- Reverts https://github.com/rust-lang/rust/pull/154070
This reverts commit 6fd8466768, reversing changes made to fda6d37bb8.
---
The changes in https://github.com/rust-lang/rust/pull/154070 are well-intentioned, but in their current form they place an unreasonable maintenance burden on the affected part of the compiler, out of proportion to the benefit gained.
- Moving the unstable options to a separate `include!` file is marginally more convenient for the unstable-book-gen tool, but a big hassle for compiler contributors looking to read or modify the list of unstable options. It breaks normal file layout conventions, interferes with navigation, and interferes with IDE features, all without ever being truly necessary.
- The extra `syn`-based parser in unstable-book-gen is quite complicated, almost entirely undocumented, and seemingly buggy. That makes it extremely difficult to understand or modify, which in turn makes it effectively impossible to ever change the `options!` macro on the compiler side.
- The new tests in unstable-book-gen don't appear to be hooked up to run in CI.
- The compiler changes don't appear to have been approved by a T-compiler reviewer.
Before contemplating a revert, I tried to put together a fix-forward to resolve or mitigate some of these issues. But unstable-book-gen in its current state makes that impractical, so unfortunately I believe that the only way forward is to revert the original changes.
---
I do think the reverted functionality is potentially useful, and I'm not fundamentally opposed to a revised version of it landing in the future, if the relevant concerns are addressed.
But I feel strongly that the current version does not justify the real and troublesome maintenance burden that it imposes on compiler contributors.
Unstable book options parser
Parses the `options!` macro in `compiler/rustc_session/src/options.rs` directly to extract the unstable (-Z) compiler flag names and descriptions to generate documentation for the unstable book.
I took notice from the previous attempt which ran `rustc -Zhelp` and parsed the output and used this approach that reads the source directly.
Used claude for the tedious char by char parsing parts but verified the code, I hope that's ok!
`rustc_hir_analysis` depends on `rustc_lint` in just a single function:
`emit_delayed_lint`, which is used by the
"emit_ast_lowering_delayed_lints" checking section within
`rustc_hir_analysis::check_crate`.
This commit moves that function and section to out of
`rustc_hir_analysis::check_crate`, into `rustc_interface`, eliminating
the dependency. This seems reasonable because the delayed lint errors
aren't really related to HIR analysis. They were in there just because
HIR analysis follows AST lowering.
This means `rustc_hir_analysis` and `rustc_lint` can both start
compiling as soon as `rustc_trait_selection` finishes. This also changes
the error order in one test, which doesn't matter.
The commit also changes `emit_delayed_lint` to `emit_delayed_lints`,
factoring out some code duplicated in rustdoc.
These lists can be considered part of the encoder state, and bundling them
inside the encoder is certainly more convenient than passing them around
separately.
feat(rustdoc-json): Add optional support for rkyv (de)serialization
## Motivation
The JSON documents produced by `rustdoc-json` are _big_. More often than not, tools need to access a small fraction of that output—e.g. a couple of types from a transitive dependency, or a subset of the fields on a given `rustdoc-json-types` type.
Using a binary (de)serialization format and a cache helps to drive down the performance cost of deserialization: you invoke `rustdoc-json` to get the JSON output you need, re-serialize it using a more perfomant format as target (e.g. `bincode` or `postcard`) and thus amortize the cost of future queries that hit the persistent cache rather than `rustdoc-json`.
This is _better_, but still not great: the deserialization cost for crates like `std` still shows up prominently in flamegraphs.
## An Alternative Approach: rkyv
`rkyv` provides a different opportunity: you avoid paying the deserialization cost _upfront_ thanks to [zero-copy deserialization](https://rkyv.org/zero-copy-deserialization.html).
You're often able to determine if you need a certain entry from the JSON document using the archived version of that type, thus incurring the full deserialization cost only for the subset of items you actually need ([example](https://github.com/LukeMathWalker/pavex/pull/574/changes/d067e7e0cfa38da5b0a3c8713b1c53beb0b29a5d)).
## The Change
This PR adds support for `rkyv` behind a feature flag (`rkyv_0_8`).
For most types, it's a straight-forward `derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)` annotation. For co-recursive types, we need to adjust the generated bounds, using the techniques from [`rkyv`'s JSON example](https://github.com/rkyv/rkyv/blob/985b0230a0b9cb9fce4a4ee9facb6af148e27c8e/rkyv/examples/json_like_schema.rs).
I have added new round-trip tests to ensure `rkyv` works as expected.
r? @aDotInTheVoid