| Age | Commit message (Collapse) | Author | Lines |
|
Because it's almost always static.
This makes `impl IntoDiagnosticArg for DiagnosticArgValue` trivial,
which is nice.
There are a few diagnostics constructed in
`compiler/rustc_mir_build/src/check_unsafety.rs` and
`compiler/rustc_mir_transform/src/errors.rs` that now need symbols
converted to `String` with `to_string` instead of `&str` with `as_str`,
but that' no big deal, and worth it for the simplifications elsewhere.
|
|
|
|
Error codes are integers, but `String` is used everywhere to represent
them. Gross!
This commit introduces `ErrCode`, an integral newtype for error codes,
replacing `String`. It also introduces a constant for every error code,
e.g. `E0123`, and removes the `error_code!` macro. The constants are
imported wherever used with `use rustc_errors::codes::*`.
With the old code, we have three different ways to specify an error code
at a use point:
```
error_code!(E0123) // macro call
struct_span_code_err!(dcx, span, E0123, "msg"); // bare ident arg to macro call
\#[diag(name, code = "E0123")] // string
struct Diag;
```
With the new code, they all use the `E0123` constant.
```
E0123 // constant
struct_span_code_err!(dcx, span, E0123, "msg"); // constant
\#[diag(name, code = E0123)] // constant
struct Diag;
```
The commit also changes the structure of the error code definitions:
- `rustc_error_codes` now just defines a higher-order macro listing the
used error codes and nothing else.
- Because that's now the only thing in the `rustc_error_codes` crate, I
moved it into the `lib.rs` file and removed the `error_codes.rs` file.
- `rustc_errors` uses that macro to define everything, e.g. the error
code constants and the `DIAGNOSTIC_TABLES`. This is in its new
`codes.rs` file.
|
|
As is already done in `rustc_span` and `rustc_data_structures`.
|
|
Co-authored-by: Michael Goulet <michael@errs.io>
|
|
|
|
|
|
|
|
We have several methods indicating the presence of errors, lint errors,
and delayed bugs. I find it frustrating that it's very unclear which one
you should use in any particular spot. This commit attempts to instill a
basic principle of "use the least general one possible", because that
reflects reality in practice -- `has_errors` is the least general one
and has by far the most uses (esp. via `abort_if_errors`).
Specifics:
- Add some comments giving some usage guidelines.
- Prefer `has_errors` to comparing `err_count` to zero.
- Remove `has_errors_or_span_delayed_bugs` because it's a weird one: in
the cases where we need to count delayed bugs, we should really be
counting lint errors as well.
- Rename `is_compilation_going_to_fail` as
`has_errors_or_lint_errors_or_span_delayed_bugs`, for consistency with
`has_errors` and `has_errors_or_lint_errors`.
- Change a few other `has_errors_or_lint_errors` calls to `has_errors`,
as per the "least general" principle.
This didn't turn out to be as neat as I hoped when I started, but I
think it's still an improvement.
|
|
|
|
|
|
`Diagnostic::code` has the type `DiagnosticId`, which has `Error` and
`Lint` variants. Plus `Diagnostic::is_lint` is a bool, which should be
redundant w.r.t. `Diagnostic::code`.
Seems simple. Except it's possible for a lint to have an error code, in
which case its `code` field is recorded as `Error`, and `is_lint` is
required to indicate that it's a lint. This is what happens with
`derive(LintDiagnostic)` lints. Which means those lints don't have a
lint name or a `has_future_breakage` field because those are stored in
the `DiagnosticId::Lint`.
It's all a bit messy and confused and seems unintentional.
This commit:
- removes `DiagnosticId`;
- changes `Diagnostic::code` to `Option<String>`, which means both
errors and lints can straightforwardly have an error code;
- changes `Diagnostic::is_lint` to `Option<IsLint>`, where `IsLint` is a
new type containing a lint name and a `has_future_breakage` bool, so
all lints can have those, error code or not.
|
|
|
|
`-Ztreat-err-as-bug` treats normal errors and delayed bugs equally,
which can lead to some really surprising results.
This commit changes `-Ztreat-err-as-bug` so it ignores delayed bugs,
unless they get promoted to proper bugs and are printed.
This feels to me much simpler and more logical. And it simplifies the
implementation:
- The `-Ztreat-err-as-bug` check is removed from in
`DiagCtxt::{delayed_bug,span_delayed_bug}`.
- `treat_err_as_bug` doesn't need to count delayed bugs.
- The `-Ztreat-err-as-bug` panic message is simpler, because it doesn't
have to mention delayed bugs.
Output of delayed bugs is now more consistent. They're always printed
the same way. Previously when they triggered `-Ztreat-err-as-bug` they
would be printed slightly differently, via `span_bug` in
`span_delayed_bug` or `delayed_bug`.
A minor behaviour change: the "no errors encountered even though
`span_delayed_bug` issued" printed before delayed bugs is now a note
rather than a bug. This is done so it doesn't get counted as an error
that might trigger `-Ztreat-err-as-bug`, which would be silly.
This means that if you use `-Ztreat-err-as-bug=1` and there are no
normal errors but there are delayed bugs, the first delayed bug will be
shown (and the panic will happen after it's printed).
Also, I have added a second note saying "those delayed bugs will now be
shown as internal compiler errors". I think this makes it clearer what
is happening, because the whole concept of delayed bugs is non-obvious.
There are some test changes.
- equality-in-canonical-query.rs: Minor output changes, and the error
count reduces by one because the "no errors encountered even though
`span_delayed_bug` issued" message is no longer counted as an error.
- rpit_tait_equality_in_canonical_query.rs: Ditto.
- storage-live.rs: The query stack disappears because these delayed bugs
are now printed at the end, rather than when they are created.
- storage-return.rs, span_delayed_bug.rs: now need
`-Zeagerly-emit-delayed-bugs` because they need the delayed bugs
emitted immediately to preserve behaviour.
|
|
|
|
|
|
There are two places that handle normal delayed bugs. This commit
factors out some repeated code.
Also, we can use `std::mem::take` instead of `std::mem::replace`.
|
|
rustfmt.toml: don't ignore just any tests path, only root one
Previously ignored any `tests` path, now only /tests at repo root.
For reference, https://git-scm.com/docs/gitignore#_pattern_format
|
|
Remove `DiagnosticBuilder::buffer`
`DiagnosticBuilder::buffer` doesn't do much, and part of what it does (for `-Ztreat-err-as-bug`) it shouldn't.
This PR strips it back, replaces its uses, and finally removes it, making a few cleanups in the vicinity along the way.
r? ``@oli-obk``
|
|
annotate-snippets: update to 0.10
Ports `annotate-snippets` to 0.10, temporary dupes versions; other crates left that depends on 0.9 is `ui_test` and `rustfmt`.
|
|
|
|
All its uses have been removed.
|
|
But we can't easily switch from `Vec<Diagnostic>` to
`Vec<DiagnosticBuilder<G>>` because there's a mix of errors and warnings
which result in different `G` types. So we must make
`DiagnosticBuilder::into_diagnostic` public, but that's ok, and it will
get more use in subsequent commits.
|
|
consideration.
It seems very wrong to have a `-Ztreat-err-as-bug` check here before the
error is even emitted.
Once that's done:
- `into_diagnostic` is infallible, so its return type doesn't need the
`Option`;
- the `&'a DiagCtxt` also isn't needed, because only one callsite uses
it, and it already have access to it via `self.dcx`;
- the comments about dcx disabling buffering are no longer true, this is
unconditional now;
- and the `debug!` seems unnecessary... the comment greatly overstates
its importance because few diagnostics come through `into_diagnostic`,
and `-Ztrack-diagnostics` exists anyway.
|
|
No point computing `warnings` and `errors` if we're going to return
early before they're used.
|
|
Errors in `DiagCtxtInner::emit_diagnostic` are never set to
`Level::Bug`, because the condition never succeeds, because
`self.treat_err_as_bug()` is called *before* the error counts are
incremented.
This commit switches to `self.treat_next_err_as_bug()`, fixing the
problem. This changes the error message output to actually say "internal
compiler error".
|
|
They have one and two call sites respectively, and they just make the
code harder to read.
|
|
Of the error levels satisfying `is_error`, `Level::Error` is the only
one that can be a lint, so there's no need to check for it.
(And even if it wasn't, it would make more sense to include
non-`Error`-but-`is_error` lints under `lint_err_count` than under
`err_count`.)
|
|
There are four functions that adjust error and warning counts:
- `stash_diagnostic` (increment)
- `steal_diagnostic` (decrement)
- `emit_stashed_diagnostics) (decrement)
- `emit_diagnostic` (increment)
The first three all behave similarly, and only update `warn_count` for
forced warnings. But the last one updates `warn_count` for both forced
and non-forced warnings.
Seems like a bug. How should it be fixed? Well, `warn_count` is only
used in one place: `DiagCtxtInner::drop`, where it's part of the
condition relating to the printing of `good_path_delayed_bugs`. The
intention of that condition seems to be "have any errors been printed?"
so this commit replaces `warn_count` with `has_printed`, which is set
when printing occurs. This is simpler than all the ahead-of-time
incrementing and decrementing.
|
|
To put it next to a similar field.
|
|
It's missing but should obviously be included.
|
|
`is_force_warn` is only possible for diagnostics with `Level::Warning`,
but it is currently stored in `Diagnostic::code`, which every diagnostic
has.
This commit:
- removes the boolean `DiagnosticId::Lint::is_force_warn` field;
- adds a `ForceWarning` variant to `Level`.
Benefits:
- The common `Level::Warning` case now has no arguments, replacing
lots of `Warning(None)` occurrences.
- `rustc_session::lint::Level` and `rustc_errors::Level` are more
similar, both having `ForceWarning` and `Warning`.
|
|
Because the values put into it are functions named `track_diagnostic`
and `default_track_diagnostic`.
|
|
This lets us avoid the use of `DiagnosticBuilder::into_diagnostic` in
miri, when then means that `DiagnosticBuilder::into_diagnostic` can
become private, being now only used by `stash` and `buffer`.
|
|
In #119606 I added them and used a `_mv` suffix, but that wasn't great.
A `with_` prefix has three different existing uses.
- Constructors, e.g. `Vec::with_capacity`.
- Wrappers that provide an environment to execute some code, e.g.
`with_session_globals`.
- Consuming chaining methods, e.g. `Span::with_{lo,hi,ctxt}`.
The third case is exactly what we want, so this commit changes
`DiagnosticBuilder::foo_mv` to `DiagnosticBuilder::with_foo`.
Thanks to @compiler-errors for the suggestion.
|
|
We have `span_delayed_bug` and often pass it a `DUMMY_SP`. This commit
adds `delayed_bug`, which matches pairs like `err`/`span_err` and
`warn`/`span_warn`.
|
|
For consistency with `warn`/`struct_warn`, and also `{create,emit}_err`,
all of which use an abbreviated form.
|
|
Because it takes an error code after the span. This avoids the confusing
overlap with the `DiagCtxt::struct_span_err` method, which doesn't take
an error code.
|
|
|
|
It was added in #54232. It seems like it was aimed at NLL development,
which is well in the past. Also, it looks like `-Ztreat-err-as-bug` can
be used to achieve the same effect. So it doesn't seem necessary.
|
|
They are no longer used, because
`{DiagCtxt,DiagCtxtInner}::emit_diagnostic` are used everywhere instead.
This also means `track_diagnostic` can become consuming.
|
|
Currently it's used for two dynamic checks:
- When a diagnostic is emitted, has it been emitted before?
- When a diagnostic is dropped, has it been emitted/cancelled?
The first check is no longer need, because `emit` is consuming, so it's
impossible to emit a `DiagnosticBuilder` twice. The second check is
still needed.
This commit replaces `DiagnosticBuilderState` with a simpler
`Option<Box<Diagnostic>>`, which is enough for the second check:
functions like `emit` and `cancel` can take the `Diagnostic` and then
`drop` can check that the `Diagnostic` was taken.
The `DiagCtxt` reference from `DiagnosticBuilderState` is now stored as
its own field, removing the need for the `dcx` method.
As well as making the code shorter and simpler, the commit removes:
- One (deprecated) `ErrorGuaranteed::unchecked_claim_error_was_emitted`
call.
- Two `FIXME(eddyb)` comments that are no longer relevant.
- The use of a dummy `Diagnostic` in `into_diagnostic`.
Nice!
|
|
This is now possible, thanks to changes in previous commits.
|
|
The existing uses are replaced in one of three ways.
- In a function that also has calls to `emit`, just rearrange the code
so that exactly one of `delay_as_bug` or `emit` is called on every
path.
- In a function returning a `DiagnosticBuilder`, use
`downgrade_to_delayed_bug`. That's good enough because it will get
emitted later anyway.
- In `unclosed_delim_err`, one set of errors is being replaced with
another set, so just cancel the original errors.
|
|
A nice cleanup: it's now impossible to directly emit a
`DiagnosticBuilder` without consuming it.
|
|
These all have relatively low use, and can be perfectly emulated with
a simpler construction method combined with `code` or `code_mv`.
|
|
To avoid the use of a mutable local variable, and because it reads more
nicely.
|
|
This works for most of its call sites. This is nice, because `emit` very
much makes sense as a consuming operation -- indeed,
`DiagnosticBuilderState` exists to ensure no diagnostic is emitted
twice, but it uses runtime checks.
For the small number of call sites where a consuming emit doesn't work,
the commit adds `DiagnosticBuilder::emit_without_consuming`. (This will
be removed in subsequent commits.)
Likewise, `emit_unless` becomes consuming. And `delay_as_bug` becomes
consuming, while `delay_as_bug_without_consuming` is added (which will
also be removed in subsequent commits.)
All this requires significant changes to `DiagnosticBuilder`'s chaining
methods. Currently `DiagnosticBuilder` method chaining uses a
non-consuming `&mut self -> &mut Self` style, which allows chaining to
be used when the chain ends in `emit()`, like so:
```
struct_err(msg).span(span).emit();
```
But it doesn't work when producing a `DiagnosticBuilder` value,
requiring this:
```
let mut err = self.struct_err(msg);
err.span(span);
err
```
This style of chaining won't work with consuming `emit` though. For
that, we need to use to a `self -> Self` style. That also would allow
`DiagnosticBuilder` production to be chained, e.g.:
```
self.struct_err(msg).span(span)
```
However, removing the `&mut self -> &mut Self` style would require that
individual modifications of a `DiagnosticBuilder` go from this:
```
err.span(span);
```
to this:
```
err = err.span(span);
```
There are *many* such places. I have a high tolerance for tedious
refactorings, but even I gave up after a long time trying to convert
them all.
Instead, this commit has it both ways: the existing `&mut self -> Self`
chaining methods are kept, and new `self -> Self` chaining methods are
added, all of which have a `_mv` suffix (short for "move"). Changes to
the existing `forward!` macro lets this happen with very little
additional boilerplate code. I chose to add the suffix to the new
chaining methods rather than the existing ones, because the number of
changes required is much smaller that way.
This doubled chainging is a bit clumsy, but I think it is worthwhile
because it allows a *lot* of good things to subsequently happen. In this
commit, there are many `mut` qualifiers removed in places where
diagnostics are emitted without being modified. In subsequent commits:
- chaining can be used more, making the code more concise;
- more use of chaining also permits the removal of redundant diagnostic
APIs like `struct_err_with_code`, which can be replaced easily with
`struct_err` + `code_mv`;
- `emit_without_diagnostic` can be removed, which simplifies a lot of
machinery, removing the need for `DiagnosticBuilderState`.
|
|
It seems like a bad idea, just asking for diagnostics to be emitted
multiple times.
|
|
|