Skip to content

Commit e39436d

Browse files
committed
Add arguments sharing and isolation section in diagnostic-struct of rdg
Signed-off-by: xizheyin <xizheyin@smail.nju.edu.cn>
1 parent 5975693 commit e39436d

File tree

1 file changed

+39
-8
lines changed

1 file changed

+39
-8
lines changed

src/diagnostics/diagnostic-structs.md

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
11
# Diagnostic and subdiagnostic structs
22
rustc has three diagnostic traits that can be used to create diagnostics:
3-
`Diagnostic`, `LintDiagnostic`, and `Subdiagnostic`. For simple diagnostics,
4-
instead of using the `Diag` API to create and emit diagnostics,
5-
derived impls can be used. They are only suitable for simple diagnostics that
3+
`Diagnostic`, `LintDiagnostic`, and `Subdiagnostic`.
4+
5+
For simple diagnostics,
6+
derived impls can be used, e.g. `#[derive(Diagnostic)]`. They are only suitable for simple diagnostics that
67
don't require much logic in deciding whether or not to add additional
78
subdiagnostics.
89

9-
Such diagnostic can be translated into
10-
different languages and each has a slug that uniquely identifies the
11-
diagnostic.
10+
In cases where diagnostics require more complex or dynamic behavior, such as conditionally adding subdiagnostics,
11+
customizing the rendering logic, or selecting messages at runtime, you will need to manually implement
12+
the corresponding trait (`Diagnostic`, `LintDiagnostic`, or `Subdiagnostic`).
13+
This approach provides greater flexibility and is recommended for diagnostics that go beyond simple, static structures.
14+
15+
Diagnostic can be translated into different languages and each has a slug that uniquely identifies the diagnostic.
1216

1317
## `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]`
1418

@@ -142,7 +146,7 @@ tcx.dcx().emit_err(FieldAlreadyDeclared {
142146
});
143147
```
144148

145-
### Reference
149+
### Reference for `#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]`
146150
`#[derive(Diagnostic)]` and `#[derive(LintDiagnostic)]` support the
147151
following attributes:
148152

@@ -330,7 +334,34 @@ function ([example][subdiag_use_1] and [example][subdiag_use_2]) on a
330334
diagnostic or by assigning it to a `#[subdiagnostic]`-annotated field of a
331335
diagnostic struct.
332336

333-
### Reference
337+
### Argument sharing and isolation
338+
339+
Subdiagnostics will add their own arguments,
340+
i.e. some fields in their struct, into the subdiagnostic when rendering the message,
341+
so that the parameters in the main diagnostic can be used.
342+
However, when a subdiagnostic is added to a main diagnostic by implementing `#[derive(Subdiagnostic)]`,
343+
the following rules, introduced in [rust-lang/rust#142724](https://github.com/rust-lang/rust/pull/142724)
344+
apply to the handling of arguments (i.e., variables used in Fluent messages):
345+
346+
**Argument isolation between sub diagnostics**:
347+
Arguments set by a subdiagnostic are only available during the rendering of that subdiagnostic.
348+
After the subdiagnostic is rendered, all arguments it introduced are restore from the main diagnostic.
349+
This ensures that multiple subdiagnostics do not pollute each other's argument scope.
350+
For example, when using a `Vec<Subdiag>`, it iteratively add the same arg over and over again.
351+
352+
**Same argument override between sub and main diagnostics**:
353+
If a subdiagnostic sets a argument with the same name as a arg already in the master diagnostic,
354+
it will report an error at runtime unless both have exactly the same value.
355+
This
356+
- preserves the flexibility that can that *arguments is allowed to appear in the attributes of the subdiagnostic.
357+
For example, There is a attribute `#[suggestion(code = "{new_vis}")]` in sub-diagnostic, but `new_vis` is the field in main diagnostic struct.
358+
- prevents accidental overwriting or deletion of parameters required by the main diagnostic or other sub-diagnostics.
359+
360+
These rules guarantee that arguments injected by subdiagnostics are strictly scoped to their own rendering.
361+
The main diagnostic's arguments remain unaffected by subdiagnostic logic, even in the presence of name collisions.
362+
Additionally, subdiagnostics can access parameters from the main diagnostic with the same name when needed.
363+
364+
### Reference for `#[derive(Subdiagnostic)]`
334365
`#[derive(Subdiagnostic)]` supports the following attributes:
335366

336367
- `#[label(slug)]`, `#[help(slug)]`, `#[warning(slug)]` or `#[note(slug)]`

0 commit comments

Comments
 (0)