Manually implement PartialEq for Option<T> and specialize non-nullable types
This PR manually implements `PartialEq` and `StructuralPartialEq` for `Option`, which seems to produce slightly better codegen than the automatically derived implementation.
It also allows specializing on the `core::num::NonZero*` and `core::ptr::NonNull` types, taking advantage of the niche optimization by transmuting the `Option<T>` to `T` to be compared directly, which can be done in just two instructions.
A comparison of the original, new and specialized code generation is available [here](https://godbolt.org/z/dE4jxdYsa).
Change #[suggestion_*] attributes to use style="..."
As discussed [on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/336883-i18n/topic/.23100717.20tool_only_span_suggestion), this changes `#[(multipart_)suggestion_{short,verbose,hidden}(...)]` attributes to plain `#[(multipart_)suggestion(...)]` attributes with a `style = "{short,verbose,hidden}"` parameter.
It also adds a new style, `tool-only`, that corresponds to `tool_only_span_suggestion`/`tool_only_multipart_suggestion` and causes the suggestion to not be shown in human-readable output at all.
Best reviewed commit-by-commit, there's a bit of noise in there.
cc #100717 `@compiler-errors`
r? `@davidtwco`
Track where diagnostics were created.
This implements the `-Ztrack-diagnostics` flag, which uses `#[track_caller]` to track where diagnostics are created. It is meant as a debugging tool much like `-Ztreat-err-as-bug`.
For example, the following code...
```rust
struct A;
struct B;
fn main(){
let _: A = B;
}
```
...now emits the following error message:
```
error[E0308]: mismatched types
--> src\main.rs:5:16
|
5 | let _: A = B;
| - ^ expected struct `A`, found struct `B`
| |
| expected due to this
-Ztrack-diagnostics: created at compiler\rustc_infer\src\infer\error_reporting\mod.rs:2275:31
```
This allows porting uses of span_suggestions() to diagnostic structs.
Doesn't work for multipart_suggestions() because the rank would be
reversed - the struct would specify multiple spans, each of which has
multiple possible replacements, while multipart_suggestions() creates
multiple possible replacements, each with multiple spans.
Sometimes it is convenient to return a subdiagnostic enum where one or
more of the variants don't add anything to the diagnostic.
Signed-off-by: David Wood <david.wood@huawei.com>
Documentation comments shouldn't affect the diagnostic derive in any
way, but explicit support has to be added for ignoring the `doc`
attribute.
Signed-off-by: David Wood <david.wood@huawei.com>
Queries can provide an arbitrary expression for their description and
their caching behavior. Before, these expressions where stored in a
`rustc_query_description` macro emitted by the `rustc_queries` macro,
and then used in `rustc_query_impl` to fill out the methods for the
`QueryDescription` trait.
Instead, we now emit two new modules from `rustc_queries` containing the
functions with the expressions. `rustc_query_impl` calls these functions
now instead of invoking the macro.
Since we are now defining some of the functions in
`rustc_middle::query`, we now need all the imports for the key types
there as well.
Following the approach taken in earlier commits to separate formatting
initialization from use in the subdiagnostic derive, simplify the
diagnostic derive by removing the field-ordering logic that previously
solved this problem.
Signed-off-by: David Wood <david.wood@huawei.com>
Diagnostic derives have previously had to take special care when
ordering the generated code so that fields were not used after a move.
This is unlikely for most fields because a field is either annotated
with a subdiagnostic attribute and is thus likely a `Span` and copiable,
or is a argument, in which case it is only used once by `set_arg`
anyway.
However, format strings for code in suggestions can result in fields
being used after being moved if not ordered carefully. As a result, the
derive currently puts `set_arg` calls last (just before emission), such
as:
```rust
let diag = { /* create diagnostic */ };
diag.span_suggestion_with_style(
span,
fluent::crate::slug,
format!("{}", __binding_0),
Applicability::Unknown,
SuggestionStyle::ShowAlways
);
/* + other subdiagnostic additions */
diag.set_arg("foo", __binding_0);
/* + other `set_arg` calls */
diag.emit();
```
For eager translation, this doesn't work, as the message being
translated eagerly can assume that all arguments are available - so
arguments _must_ be set first.
Format strings for suggestion code are now separated into two parts - an
initialization line that performs the formatting into a variable, and a
usage in the subdiagnostic addition.
By separating these parts, the initialization can happen before
arguments are set, preserving the desired order so that code compiles,
while still enabling arguments to be set before subdiagnostics are
added.
```rust
let diag = { /* create diagnostic */ };
let __code_0 = format!("{}", __binding_0);
/* + other formatting */
diag.set_arg("foo", __binding_0);
/* + other `set_arg` calls */
diag.span_suggestion_with_style(
span,
fluent::crate::slug,
__code_0,
Applicability::Unknown,
SuggestionStyle::ShowAlways
);
/* + other subdiagnostic additions */
diag.emit();
```
Signed-off-by: David Wood <david.wood@huawei.com>
Add support for `eager` argument to the `subdiagnostic` attribute which
generates a call to `eager_subdiagnostic`.
Signed-off-by: David Wood <david.wood@huawei.com>
`AddToDiagnostic::add_to_diagnostic_with` is similar to the previous
`AddToDiagnostic::add_to_diagnostic` but takes a function that can be
used by the caller to modify diagnostic messages originating from the
subdiagnostic (such as performing translation eagerly).
`add_to_diagnostic` now just calls `add_to_diagnostic_with` with an
empty closure.
Signed-off-by: David Wood <david.wood@huawei.com>
In #102306, `rustc_typeck` was renamed to `rustc_hir_analysis` but the
diagnostic resources were not renamed - which is what this commit
changes.
Signed-off-by: David Wood <david.wood@huawei.com>
macros: diagnostic derive on enums
Part of #100717.
Extends `#[derive(Diagnostic)]` to work on enums too where each variant acts like a distinct diagnostic - being able to represent diagnostics this way can be quite a bit simpler for some parts of the compiler.
r? `@compiler-errors`
cc `@Xiretza`
FIX - ambiguous Diagnostic link in docs
UPDATE - rename diagnostic_items to IntoDiagnostic and AddToDiagnostic
[Gardening] FIX - formatting via `x fmt`
FIX - rebase conflicts. NOTE: Confirm wheather or not we want to handle TargetDataLayoutErrorsWrapper this way
DELETE - unneeded allow attributes in Handler method
FIX - broken test
FIX - Rebase conflict
UPDATE - rename residual _SessionDiagnostic and fix LintDiag link
On later stages, the feature is already stable.
Result of running:
rg -l "feature.let_else" compiler/ src/librustdoc/ library/ | xargs sed -s -i "s#\\[feature.let_else#\\[cfg_attr\\(bootstrap, feature\\(let_else\\)#"