Commit Graph

395 Commits

Author SHA1 Message Date
Nicholas Nethercote
97c157fe1e Tighten up ErrorGuaranteed handling.
- In `emit_producing_error_guaranteed`, only allow `Level::Error`.
- In `emit_diagnostic`, only produce `ErrorGuaranteed` for `Level` and
  `DelayedBug`. (Not `Bug` or `Fatal`. They don't need it, because the
  relevant `emit` methods abort.)
- Add/update various comments.
2024-02-07 18:57:47 +11:00
Nicholas Nethercote
8d1c20a539 Remove return value from emit_stashed_diagnostics.
It's never used.
2024-02-07 09:54:59 +11:00
Matthias Krüger
a3d3ccf098
Rollup merge of #120575 - nnethercote:simplify-codegen-diag-handling, r=estebank
Simplify codegen diagnostic handling

Some nice improvements. Details in the individual commit logs.

r? ````@estebank````
2024-02-06 19:40:06 +01:00
Matthias Krüger
5587be8164
Rollup merge of #120520 - nnethercote:rename-good-path, r=oli-obk
Some cleanups around diagnostic levels.

Plus some refactoring in and around diagnostic levels and emission. Details in the individual commit logs.

r? ````@oli-obk````
2024-02-06 19:40:06 +01:00
Nicholas Nethercote
d9508a1fd2 Make Emitter::emit_diagnostic consuming.
All the other `emit`/`emit_diagnostic` methods were recently made
consuming (e.g. #119606), but this one wasn't. But it makes sense to.

Much of this is straightforward, and lots of `clone` calls are avoided.
There are a couple of tricky bits.
- `Emitter::primary_span_formatted` no longer takes a `Diagnostic` and
  returns a pair. Instead it takes the two fields from `Diagnostic` that
  it used (`span` and `suggestions`) as `&mut`, and modifies them. This
  is necessary to avoid the cloning of `diag.children` in two emitters.
- `from_errors_diagnostic` is rearranged so various uses of `diag` occur
  before the consuming `emit_diagnostic` call.
2024-02-05 21:27:01 +11:00
Matthias Krüger
ca36ed27be
Rollup merge of #119600 - aDotInTheVoid:comment-fix, r=compiler-errors
Remove outdated references to librustc_middle

The relevant comment is now in 791a53f380/compiler/rustc_middle/src/tests.rs (L3-L13)
2024-02-05 06:37:14 +01:00
Nicholas Nethercote
59e0bc2de7 Split Level::DelayedBug in two.
The two kinds of delayed bug have quite different semantics so a
stronger conceptual separation is nice. (`is_error` is a good example,
because the two kinds have different behaviour.)

The commit also moves the `DelayedBug` variant after `Error` in `Level`,
to reflect the fact that it's weaker than `Error` -- it might trigger an
error but also might not. (The pre-existing `downgrade_to_delayed_bug`
function also reflects the notion that delayed bugs are lower/after
normal errors.)

Plus it condenses some of the comments on `Level` into a table, for
easier reading, and introduces `can_be_top_or_sub` to indicate which
levels can be used in top-level diagnostics vs. subdiagnostics.

Finally, it renames `DiagCtxtInner::span_delayed_bugs` as
`DiagCtxtInner::delayed_bugs`. The `span_` prefix is unnecessary because
some delayed bugs don't have a span.
2024-02-05 10:03:01 +11:00
Nicholas Nethercote
c367386832 Refactor emit_diagnostic.
- Combine two different blocks involving
  `diagnostic.level.get_expectation_id()` into one.
- Combine several `if`s involving `diagnostic.level` into a single
  `match`.

This requires reordering some of the operations, but this has no
functional effect.
2024-02-05 10:02:26 +11:00
Nicholas Nethercote
e8c3cbf44b Make Diagnostic::is_error return false for Level::FailureNote.
It doesn't affect behaviour, but makes sense with (a) `FailureNote` having
`()` as its emission guarantee, and (b) in `Level` the `is_error` levels
now are all listed before the non-`is_error` levels.
2024-02-05 08:16:30 +11:00
Nicholas Nethercote
be64802854 Use StringPart more. 2024-02-03 09:02:50 +11:00
Nicholas Nethercote
0621cd46f2 Simplify future breakage control flow.
`emit_future_breakage` calls
`self.dcx().take_future_breakage_diagnostics()` and then passes the
result to `self.dcx().emit_future_breakage_report(diags)`. This commit
removes the first of these and lets `emit_future_breakage_report` do the
taking.

It also inlines and removes what is left of `emit_future_breakage`,
which has a single call site.
2024-02-03 09:02:50 +11:00
Nicholas Nethercote
df322fc29f Remove some unnecessary clone calls. 2024-02-03 09:02:50 +11:00
Nicholas Nethercote
a9a2e1565a Diagnostic cleanups
- `emitted_at` isn't used outside the crate.
- `code` and `messages` are public fields, so there's no point have
  trivial getters/setters for them.
- `suggestions` is public, so the comment about "functionality on
  `Diagnostic`" isn't needed.
2024-02-03 09:02:50 +11:00
Nicholas Nethercote
585367f15f Remove an out-of-date comment.
`DiagnosticBuilderInner` was removed some time ago.
2024-02-03 09:02:50 +11:00
Nicholas Nethercote
3434466a7f Tweak emit_stashed_diagnostics.
`take` + `into_iter` + pattern matching is nicer than `drain` + `map` +
`collect`.
2024-02-01 19:18:45 +11:00
Guillaume Gomez
ee2e9e1eda
Rollup merge of #118533 - chenyukang:yukang-fix-118455, r=petrochenkov
Suppress unhelpful diagnostics for unresolved top level attributes

Fixes #118455, unresolved top level attribute error didn't imported prelude and already have emitted an error, report builtin macro and attributes error by the way, so `check_invalid_crate_level_attr` in can ignore them.

Also fixes #89566, fixes #67107.

r? `@petrochenkov`
2024-01-30 16:57:46 +01:00
Nicholas Nethercote
514a5d8d55 Remove the second lifetime from DiagnosticArg.
Because it's always static.

I'm surprised the compiler allowed this unused lifetime without any
complaint.
2024-01-30 18:46:08 +11:00
Nicholas Nethercote
06aa381adb Remove DiagnosticArgName from rustc_codegen_ssa.
It's identical to the one in `rustc_errors`; use that instead.

Also remove some `rustc_errors::` qualifiers.
2024-01-30 18:46:08 +11:00
yukang
492df34eea Supress unhelpful diagnostics for unresolved top level attributes 2024-01-29 17:43:07 +08:00
Nicholas Nethercote
5d9dfbd08f Stop using String for error codes.
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.
2024-01-29 07:41:41 +11:00
Nicholas Nethercote
d91d164b00 Sort attributes in compiler/rustc_errors/src/lib.rs.
As is already done in `rustc_span` and `rustc_data_structures`.
2024-01-29 07:40:08 +11:00
clubby789
fd29f74ff8 Remove unused features 2024-01-25 14:01:33 +00:00
Nicholas Nethercote
1f9fa2305a Tweak error counting.
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.
2024-01-22 10:14:01 +11:00
Nicholas Nethercote
807c8687de Count "unused extern" errors as lints rather than normal errors. 2024-01-22 10:14:01 +11:00
Nicholas Nethercote
f00c088393 Clarify comments about diagnostic count fields. 2024-01-22 10:14:00 +11:00
Nicholas Nethercote
d71f535a6f Rework how diagnostic lints are stored.
`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.
2024-01-14 14:04:25 +11:00
Nicholas Nethercote
f1ac54123f Don't consider delayed bugs for -Ztreat-err-as-bug.
`-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.
2024-01-13 09:59:56 +11:00
Michael Goulet
7df43d3c81 Give me a way to emit all the delayed bugs 2024-01-12 03:30:17 +00:00
Michael Goulet
eb79bc0470 Good path bugs are just a flavor of delayed bug 2024-01-12 03:29:59 +00:00
Nicholas Nethercote
3330940f7f Avoid repetition in flush_delayed calls.
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`.
2024-01-12 10:25:22 +11:00
Nicholas Nethercote
a0f5431e23 Move code around.
No point computing `warnings` and `errors` if we're going to return
early before they're used.
2024-01-11 16:55:10 +11:00
Nicholas Nethercote
2aac288c18 Use the right level with -Ztreat-err-as-bug.
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".
2024-01-11 16:55:10 +11:00
Nicholas Nethercote
f0a3684c1e Inline and remove DiagCtxtInner::bump_{lint_err,err}_count.
They have one and two call sites respectively, and they just make the
code harder to read.
2024-01-11 16:54:22 +11:00
Nicholas Nethercote
dd61eba3c3 Simplify lint error counting.
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`.)
2024-01-11 07:56:20 +11:00
Nicholas Nethercote
56c3265c7b Replace warn_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.
2024-01-11 07:56:20 +11:00
Nicholas Nethercote
8866780d02 Move DiagCtxtInner::deduplicated_warn_count.
To put it next to a similar field.
2024-01-11 07:56:20 +11:00
Nicholas Nethercote
12ba450d14 Reset lint_err_count in DiagCtxt::reset_err_count.
It's missing but should obviously be included.
2024-01-11 07:56:20 +11:00
Nicholas Nethercote
0e388f2192 Change how force-warn lint diagnostics are recorded.
`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`.
2024-01-11 07:56:17 +11:00
Nicholas Nethercote
06cf881969 Rename TRACK_DIAGNOSTICS as TRACK_DIAGNOSTIC.
Because the values put into it are functions named `track_diagnostic`
and `default_track_diagnostic`.
2024-01-11 07:55:03 +11:00
Nicholas Nethercote
ed76b0b882 Rename consuming chaining methods on DiagnosticBuilder.
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.
2024-01-10 07:40:00 +11:00
Nicholas Nethercote
2ea7a37e11 Add DiagCtxt::delayed_bug.
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`.
2024-01-10 07:33:07 +11:00
Nicholas Nethercote
3c4f1d85af Rename {create,emit}_warning as {create,emit}_warn.
For consistency with `warn`/`struct_warn`, and also `{create,emit}_err`,
all of which use an abbreviated form.
2024-01-10 07:33:06 +11:00
Nicholas Nethercote
99b1b0f85c Fix incorrect comment. 2024-01-10 07:17:55 +11:00
Nicholas Nethercote
a2b765fc37 Remove -Zdont-buffer-diagnostics.
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.
2024-01-09 09:47:36 +11:00
Nicholas Nethercote
db09eb2d3a Remove {DiagCtxt,DiagCtxtInner}::emit_diagnostic_without_consuming.
They are no longer used, because
`{DiagCtxt,DiagCtxtInner}::emit_diagnostic` are used everywhere instead.

This also means `track_diagnostic` can become consuming.
2024-01-08 16:18:55 +11:00
Nicholas Nethercote
2d91c6d1bf Remove DiagnosticBuilderState.
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!
2024-01-08 16:18:54 +11:00
Nicholas Nethercote
6682f243dc Remove all eight DiagnosticBuilder::*_with_code methods.
These all have relatively low use, and can be perfectly emulated with
a simpler construction method combined with `code` or `code_mv`.
2024-01-08 16:00:34 +11:00
Nicholas Nethercote
589591efde Use chaining in DiagnosticBuilder construction.
To avoid the use of a mutable local variable, and because it reads more
nicely.
2024-01-08 15:43:07 +11:00
Nicholas Nethercote
ca2fc426a9 Remove Clone impl for DiagnosticBuilder.
It seems like a bad idea, just asking for diagnostics to be emitted
multiple times.
2024-01-08 12:05:40 +11:00
Alona Enraght-Moony
16e117cf96 Remove outdated references to librustc_middle. 2024-01-05 16:34:52 +00:00