Skip to content

Commit e3d8733

Browse files
nnethercotetshepang
authored andcommitted
Some updates for recent diagnostics changes.
1 parent af8e2fe commit e3d8733

9 files changed

+71
-69
lines changed

src/bug-fix-procedure.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ Let's say that we've adopted `E0592` as our code. Then we can change the
313313
`add_lint()` call above to something like:
314314

315315
```rust
316-
struct_span_err!(self.tcx.sess, self.tcx.span_of_impl(item1).unwrap(), msg)
316+
struct_span_code_err!(self.dcx(), self.tcx.span_of_impl(item1).unwrap(), E0592, msg)
317317
.emit();
318318
```
319319

src/compiler-debugging.md

+9-6
Original file line numberDiff line numberDiff line change
@@ -108,12 +108,8 @@ stack backtrace:
108108

109109
If you want to get a backtrace to the point where the compiler emits an
110110
error message, you can pass the `-Z treat-err-as-bug=n`, which will make
111-
the compiler panic on the `nth` error on `span_delayed_bug`. If you leave
112-
off `=n`, the compiler will assume `1` for `n` and thus panic on the
113-
first error it encounters.
114-
115-
This can also help when debugging `span_delayed_bug` calls - it will make
116-
the first `span_delayed_bug` call panic, which will give you a useful backtrace.
111+
the compiler panic on the `nth` error. If you leave off `=n`, the compiler will
112+
assume `1` for `n` and thus panic on the first error it encounters.
117113

118114
For example:
119115

@@ -184,6 +180,13 @@ stack backtrace:
184180

185181
Cool, now I have a backtrace for the error!
186182

183+
## Debugging delayed bugs
184+
185+
The `-Z eagerly-emit-delayed-bugs` option makes it easy to debug delayed bugs.
186+
It turns them into normal errors, i.e. makes them visible. This can be used in
187+
combination with `-Z treat-err-as-bug` to stop at a particular delayed bug and
188+
get a backtrace.
189+
187190
## Getting the error creation location
188191

189192
`-Z track-diagnostics` can help figure out where errors are emitted. It uses `#[track_caller]`

src/diagnostics.md

+27-31
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ LL | more code
3030
(See [diagnostic levels](#diagnostic-levels))
3131
- Code (for example, for "mismatched types", it is `E0308`). It helps
3232
users get more information about the current error through an extended
33-
description of the problem in the error code index. Diagnostics created
34-
by lints don't have a code in the emitted message.
33+
description of the problem in the error code index. Not all diagnostic have a
34+
code. For example, diagnostics created by lints don't have one.
3535
- Message. It is the main description of the problem. It should be general and
3636
able to stand on its own, so that it can make sense even in isolation.
3737
- Diagnostic window. This contains several things:
@@ -116,7 +116,7 @@ Here are a few examples:
116116
so warnings are instead emitted,
117117
and will eventually be turned into fixed (hard) errors.
118118

119-
Hard-coded warnings (those using the `span_warn` methods) should be avoided
119+
Hard-coded warnings (those using methods like `span_warn`) should be avoided
120120
for normal code, preferring to use lints instead. Some cases, such as warnings
121121
with CLI flags, will require the use of hard-coded warnings.
122122

@@ -139,7 +139,7 @@ use an error-level lint instead of a fixed error.
139139
- The word "illegal" is illegal. Prefer "invalid" or a more specific word
140140
instead.
141141
- Errors should document the span of code where they occur (use
142-
[`rustc_errors::diagnostic_builder::DiagnosticBuilder`][diagbuild]'s
142+
[`rustc_errors::DiagCtxt`][DiagCtxt]'s
143143
`span_*` methods or a diagnostic struct's `#[primary_span]` to easily do
144144
this). Also `note` other spans that have contributed to the error if the span
145145
isn't too large.
@@ -324,14 +324,12 @@ described below can be used as normal.
324324

325325
[diagnostic-structs]: ./diagnostics/diagnostic-structs.md
326326

327-
[`Session`][session] and [`ParseSess`][parsesses] have
328-
methods (or fields with methods) that allow reporting errors. These methods
327+
[`DiagCtxt`][DiagCtxt] has methods that create and emit errors. These methods
329328
usually have names like `span_err` or `struct_span_err` or `span_warn`, etc...
330329
There are lots of them; they emit different types of "errors", such as
331330
warnings, errors, fatal errors, suggestions, etc.
332331

333-
[parsesses]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/parse/struct.ParseSess.html
334-
[session]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html
332+
[DiagCtxt]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxt.html
335333

336334
In general, there are two classes of such methods: ones that emit an error
337335
directly and ones that allow finer control over what to emit. For example,
@@ -350,15 +348,15 @@ before emitting it by calling the [`emit`][emit] method. (Failing to either
350348
emit or [cancel][cancel] a `DiagnosticBuilder` will result in an ICE.) See the
351349
[docs][diagbuild] for more info on what you can do.
352350

353-
[spanerr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html#method.span_err
354-
[strspanerr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html#method.struct_span_err
351+
[spanerr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxt.html#method.span_err
352+
[strspanerr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxt.html#method.struct_span_err
355353
[diagbuild]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html
356354
[emit]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html#method.emit
357-
[cancel]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.Diagnostic.html#method.cancel
355+
[cancel]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/diagnostic_builder/struct.DiagnosticBuilder.html#method.cancel
358356

359357
```rust,ignore
360358
// Get a DiagnosticBuilder. This does _not_ emit an error yet.
361-
let mut err = sess.struct_span_err(sp, fluent::example::example_error);
359+
let mut err = sess.dcx.struct_span_err(sp, fluent::example::example_error);
362360
363361
// In some cases, you might need to check if `sp` is generated by a macro to
364362
// avoid printing weird errors about macro-generated code.
@@ -421,7 +419,7 @@ apply them)
421419
For example, to make our `qux` suggestion machine-applicable, we would do:
422420

423421
```rust,ignore
424-
let mut err = sess.struct_span_err(sp, fluent::example::message);
422+
let mut err = sess.dcx.struct_span_err(sp, fluent::example::message);
425423
426424
if let Ok(snippet) = sess.source_map().span_to_snippet(sp) {
427425
err.span_suggestion(
@@ -644,24 +642,22 @@ fn pierce_parens(mut expr: &ast::Expr) -> &ast::Expr {
644642
// list of methods.
645643
impl EarlyLintPass for WhileTrue {
646644
fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
647-
if let ast::ExprKind::While(cond, ..) = &e.kind {
648-
if let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind {
649-
if let ast::LitKind::Bool(true) = lit.kind {
650-
if !lit.span.from_expansion() {
651-
let condition_span = cx.sess.source_map().guess_head_span(e.span);
652-
cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| {
653-
lint.build(fluent::example::use_loop)
654-
.span_suggestion_short(
655-
condition_span,
656-
fluent::example::suggestion,
657-
"loop".to_owned(),
658-
Applicability::MachineApplicable,
659-
)
660-
.emit();
661-
})
662-
}
663-
}
664-
}
645+
if let ast::ExprKind::While(cond, ..) = &e.kind
646+
&& let ast::ExprKind::Lit(ref lit) = pierce_parens(cond).kind
647+
&& let ast::LitKind::Bool(true) = lit.kind
648+
&& !lit.span.from_expansion()
649+
{
650+
let condition_span = cx.sess.source_map().guess_head_span(e.span);
651+
cx.struct_span_lint(WHILE_TRUE, condition_span, |lint| {
652+
lint.build(fluent::example::use_loop)
653+
.span_suggestion_short(
654+
condition_span,
655+
fluent::example::suggestion,
656+
"loop".to_owned(),
657+
Applicability::MachineApplicable,
658+
)
659+
.emit();
660+
})
665661
}
666662
}
667663
}

src/diagnostics/diagnostic-structs.md

+14-13
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
11
# Diagnostic and subdiagnostic structs
2-
rustc has two diagnostic derives that can be used to create simple diagnostics,
2+
rustc has three diagnostic derives that can be used to create simple diagnostics,
33
which are recommended to be used when they are applicable:
4-
`#[derive(Diagnostic)]` and `#[derive(Subdiagnostic)]`.
4+
`#[derive(Diagnostic)]`, #[derive(LintDiagnostic)], and `#[derive(Subdiagnostic)]`.
55

66
Diagnostics created with the derive macros can be translated into different
77
languages and each has a slug that uniquely identifies the diagnostic.
88

9-
## `#[derive(Diagnostic)]`
9+
## `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]`
1010
Instead of using the `DiagnosticBuilder` API to create and emit diagnostics,
11-
the `Diagnostic` derive can be used. `#[derive(Diagnostic)]` is
12-
only applicable for simple diagnostics that don't require much logic in
13-
deciding whether or not to add additional subdiagnostics.
11+
these derives can be used. They are only applicable for simple diagnostics that
12+
don't require much logic in deciding whether or not to add additional
13+
subdiagnostics.
1414

1515
Consider the [definition][defn] of the "field already declared" diagnostic
1616
shown below:
1717

1818
```rust,ignore
1919
#[derive(Diagnostic)]
20-
#[diag(hir_analysis_field_already_declared, code = "E0124")]
20+
#[diag(hir_analysis_field_already_declared, code = E0124)]
2121
pub struct FieldAlreadyDeclared {
2222
pub field_name: Ident,
2323
#[primary_span]
@@ -113,17 +113,18 @@ In the end, the `Diagnostic` derive will generate an implementation of
113113
`IntoDiagnostic` that looks like the following:
114114

115115
```rust,ignore
116-
impl IntoDiagnostic<'_> for FieldAlreadyDeclared {
117-
fn into_diagnostic(self, handler: &'_ rustc_errors::Handler) -> DiagnosticBuilder<'_> {
118-
let mut diag = handler.struct_err(rustc_errors::fluent::hir_analysis_field_already_declared);
116+
impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a> for FieldAlreadyDeclared {
117+
fn into_diagnostic(self, dcx: &'a DiagCtxt, level: Level) -> DiagnosticBuilder<'a, G> {
118+
let mut diag =
119+
DiagnosticBuilder::new(dcx, level, fluent::hir_analysis_field_already_declared);
119120
diag.set_span(self.span);
120121
diag.span_label(
121122
self.span,
122-
rustc_errors::fluent::hir_analysis_label
123+
fluent::hir_analysis_label
123124
);
124125
diag.span_label(
125126
self.prev_span,
126-
rustc_errors::fluent::hir_analysis_previous_decl_label
127+
fluent::hir_analysis_previous_decl_label
127128
);
128129
diag
129130
}
@@ -135,7 +136,7 @@ straightforward, just create an instance of the struct and pass it to
135136
`emit_err` (or `emit_warning`):
136137

137138
```rust,ignore
138-
tcx.sess.emit_err(FieldAlreadyDeclared {
139+
tcx.dcx().emit_err(FieldAlreadyDeclared {
139140
field_name: f.ident,
140141
span: f.span,
141142
prev_span,

src/diagnostics/error-codes.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,10 @@ register_diagnostics! {
7070
}
7171
```
7272

73-
To actually issue the error, you can use the `struct_span_err!` macro:
73+
To actually issue the error, you can use the `struct_span_code_err!` macro:
7474

7575
```rust
76-
struct_span_err!(self.tcx.sess, // some path to the session here
76+
struct_span_code_err!(self.dcx(), // some path to the `DiagCtxt` here
7777
span, // whatever span in the source you want
7878
E0592, // your new error code
7979
fluent::example::an_error_message)
@@ -84,7 +84,7 @@ If you want to add notes or other snippets, you can invoke methods before you
8484
call `.emit()`:
8585

8686
```rust
87-
struct_span_err!(...)
87+
struct_span_code_err!(...)
8888
.span_label(another_span, fluent::example::example_label)
8989
.span_note(another_span, fluent::example::separate_note)
9090
.emit()

src/diagnostics/error-guaranteed.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ error code path leads to a failure.
1414
There are some important considerations about the usage of `ErrorGuaranteed`:
1515

1616
* It does _not_ convey information about the _kind_ of error. For example, the
17-
error may be due (indirectly) to a `span_delayed_bug` or other compiler error.
17+
error may be due (indirectly) to a delayed bug or other compiler error.
1818
Thus, you should not rely on
1919
`ErrorGuaranteed` when deciding whether to emit an error, or what kind of error
2020
to emit.
@@ -23,7 +23,7 @@ There are some important considerations about the usage of `ErrorGuaranteed`:
2323
_has already been_ emitted -- that is, the [`emit()`][emit] function has
2424
already been called. For example, if we detect that a future part of the
2525
compiler will error, we _cannot_ use `ErrorGuaranteed` unless we first emit
26-
an error ourselves.
26+
an error or delayed bug ourselves.
2727

2828
Thankfully, in most cases, it should be statically impossible to abuse
2929
`ErrorGuaranteed`.

src/diagnostics/lintstore.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Registration of these lints happens in the [`rustc_lint::register_internals`]
7676
function which is called when constructing a new lint store inside
7777
[`rustc_lint::new_lint_store`].
7878

79-
### Builtin Lints
79+
#### Builtin Lints
8080

8181
These are primarily described in two places,
8282
`rustc_lint_defs::builtin` and `rustc_lint::builtin`.

src/diagnostics/translation.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@ rustc's diagnostic infrastructure supports translatable diagnostics using
77

88
There are two ways of writing translatable diagnostics:
99

10-
1. For simple diagnostics, using a diagnostic (or subdiagnostic) derive
11-
("simple" diagnostics being those that don't require a lot of logic in
10+
1. For simple diagnostics, using a diagnostic (or subdiagnostic) derive.
11+
("Simple" diagnostics being those that don't require a lot of logic in
1212
deciding to emit subdiagnostics and can therefore be represented as
1313
diagnostic structs). See [the diagnostic and subdiagnostic structs
1414
documentation](./diagnostic-structs.md).
1515
2. Using typed identifiers with `DiagnosticBuilder` APIs (in
16-
`Diagnostic` implementations).
16+
`IntoDiagnostic` or `AddToDiagnostic` or `DecorateLint` implementations).
1717

1818
When adding or changing a translatable diagnostic,
1919
you don't need to worry about the translations.

src/ty.md

+11-9
Original file line numberDiff line numberDiff line change
@@ -342,24 +342,26 @@ emitting an error to the user, then this could cause later errors to be suppress
342342
compilation might inadvertently succeed!
343343

344344
Sometimes there is a third case. You believe that an error has been reported, but you believe it
345-
would've been reported earlier in the compilation, not locally. In that case, you can invoke
346-
[`span_delayed_bug`] This will make a note that you expect compilation to yield an error -- if
347-
however compilation should succeed, then it will trigger a compiler bug report.
345+
would've been reported earlier in the compilation, not locally. In that case, you can create a
346+
"delayed bug" with [`delayed_bug`] or [`span_delayed_bug`]. This will make a note that you expect
347+
compilation to yield an error -- if however compilation should succeed, then it will trigger a
348+
compiler bug report.
348349

350+
[`delayed_bug`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxt.html#method.delayed_bug
349351
[`span_delayed_bug`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_errors/struct.DiagCtxt.html#method.span_delayed_bug
350352

351353
For added safety, it's not actually possible to produce a `TyKind::Error` value
352354
outside of [`rustc_middle::ty`][ty]; there is a private member of
353355
`TyKind::Error` that prevents it from being constructable elsewhere. Instead,
354-
one should use the [`TyCtxt::ty_error`][terr] or
355-
[`TyCtxt::ty_error_with_message`][terrmsg] methods. These methods automatically
356-
call `span_delayed_bug` before returning an interned `Ty` of kind `Error`. If you
356+
one should use the [`Ty::new_error`][terr] or
357+
[`Ty::new_error_with_message`][terrmsg] methods. These methods either take an `ErrorGuaranteed`
358+
or call `span_delayed_bug` before returning an interned `Ty` of kind `Error`. If you
357359
were already planning to use [`span_delayed_bug`], then you can just pass the
358360
span and message to [`ty_error_with_message`][terrmsg] instead to avoid
359-
delaying a redundant span bug.
361+
a redundant delayed bug.
360362

361-
[terr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.ty_error
362-
[terrmsg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html#method.ty_error_with_message
363+
[terr]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.new_error
364+
[terrmsg]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.Ty.html#method.new_error_with_message
363365

364366
## Question: Why not substitute “inside” the `AdtDef`?
365367

0 commit comments

Comments
 (0)