summaryrefslogtreecommitdiffstats
path: root/src/doc/rustc-dev-guide/src/diagnostics
diff options
context:
space:
mode:
Diffstat (limited to 'src/doc/rustc-dev-guide/src/diagnostics')
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md79
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md159
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/lintstore.md45
-rw-r--r--src/doc/rustc-dev-guide/src/diagnostics/translation.md27
4 files changed, 187 insertions, 123 deletions
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md
index b6b6e0fa9..dcaba533e 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-items.md
@@ -1,4 +1,5 @@
# Diagnostic Items
+
While writing lints it's common to check for specific types, traits and
functions. This raises the question on how to check for these. Types can be
checked by their complete type path. However, this requires hard coding paths
@@ -7,7 +8,8 @@ rustc has introduced diagnostic items that are used to identify types via
[`Symbol`]s.
## Finding diagnostic items
-Diagnostic items are added to items inside `rustc`/`std`/`core` with the
+
+Diagnostic items are added to items inside `rustc`/`std`/`core`/`alloc` with the
`rustc_diagnostic_item` attribute. The item for a specific type can be found by
opening the source code in the documentation and looking for this attribute.
Note that it's often added with the `cfg_attr` attribute to avoid compilation
@@ -19,12 +21,15 @@ errors during tests. A definition often looks like this:
struct Penguin;
```
-Diagnostic items are usually only added to traits, types and standalone
-functions. If the goal is to check for an associated type or method, please use
-the diagnostic item of the item and reference [*How To Use Diagnostic
-Items*](#how-to-use-diagnostic-items).
+Diagnostic items are usually only added to traits,
+types,
+and standalone functions.
+If the goal is to check for an associated type or method,
+please use the diagnostic item of the item and reference
+[*Using Diagnostic Items*](#using-diagnostic-items).
## Adding diagnostic items
+
A new diagnostic item can be added with these two steps:
1. Find the target item inside the Rust repo. Now add the diagnostic item as a
@@ -43,45 +48,55 @@ A new diagnostic item can be added with these two steps:
For the naming conventions of diagnostic items, please refer to
[*Naming Conventions*](#naming-conventions).
-2. As of <!-- date: 2022-02 --> February 2022, diagnostic items in code are
- accessed via symbols in [`rustc_span::symbol::sym`]. To add your newly
- created diagnostic item simply open the module file and add the name (In
- this case `Cat`) at the correct point in the list.
+2. <!-- date-check: Aug 2022 -->
+ Diagnostic items in code are accessed via symbols in
+ [`rustc_span::symbol::sym`].
+ To add your newly-created diagnostic item,
+ simply open the module file,
+ and add the name (In this case `Cat`) at the correct point in the list.
-Now you can create a pull request with your changes. :tada: (Note that when
-using diagnostic items in other projects like Clippy, it might take some time
-until the repos get synchronized.)
+Now you can create a pull request with your changes. :tada:
+
+> NOTE:
+> When using diagnostic items in other projects like Clippy,
+> it might take some time until the repos get synchronized.
## Naming conventions
-Diagnostic items don't have a set in stone naming convention yet. These are
-some guidelines that should be used for the future, but might differ from
-existing names:
-
-* Types, traits and enums are named using UpperCamelCase (Examples: `Iterator`,
-* `HashMap`, ...)
-* For type names that are used multiple times like `Writer` it's good to choose
- a more precise name, maybe by adding the module to it. (Example: `IoWriter`)
-* Associated items should not get their own diagnostic items, but instead be
- accessed indirectly by the diagnostic item of the type they're originating
- from.
+
+Diagnostic items don't have a naming convention yet.
+Following are some guidelines that should be used in future,
+but might differ from existing names:
+
+* Types, traits, and enums are named using UpperCamelCase
+ (Examples: `Iterator` and `HashMap`)
+* For type names that are used multiple times,
+ like `Writer`,
+ it's good to choose a more precise name,
+ maybe by adding the module to it
+ (Example: `IoWriter`)
+* Associated items should not get their own diagnostic items,
+ but instead be accessed indirectly by the diagnostic item
+ of the type they're originating from.
* Freestanding functions like `std::mem::swap()` should be named using
- `snake_case` with one important (export) module as a prefix (Example:
- `mem_swap`, `cmp_max`)
+ `snake_case` with one important (export) module as a prefix
+ (Examples: `mem_swap` and `cmp_max`)
* Modules should usually not have a diagnostic item attached to them.
- Diagnostic items were added to avoid the usage of paths, using them on
- modules would therefore most likely to be counterproductive.
+ Diagnostic items were added to avoid the usage of paths,
+ and using them on modules would therefore most likely be counterproductive.
## Using diagnostic items
+
In rustc, diagnostic items are looked up via [`Symbol`]s from inside the
[`rustc_span::symbol::sym`] module. These can then be mapped to [`DefId`]s
using [`TyCtxt::get_diagnostic_item()`] or checked if they match a [`DefId`]
using [`TyCtxt::is_diagnostic_item()`]. When mapping from a diagnostic item to
a [`DefId`], the method will return a `Option<DefId>`. This can be `None` if
either the symbol isn't a diagnostic item or the type is not registered, for
-instance when compiling with `#[no_std]`. All following examples are based on
-[`DefId`]s and their usage.
+instance when compiling with `#[no_std]`.
+All the following examples are based on [`DefId`]s and their usage.
### Example: Checking for a type
+
```rust
use rustc_span::symbol::sym;
@@ -96,6 +111,7 @@ fn example_1(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
```
### Example: Checking for a trait implementation
+
```rust
/// This example checks if a given [`DefId`] from a method is part of a trait
/// implementation defined by a diagnostic item.
@@ -112,6 +128,7 @@ fn is_diag_trait_item(
```
### Associated Types
+
Associated types of diagnostic items can be accessed indirectly by first
getting the [`DefId`] of the trait and then calling
[`TyCtxt::associated_items()`]. This returns an [`AssocItems`] object which can
@@ -119,13 +136,15 @@ be used for further checks. Checkout
[`clippy_utils::ty::get_iterator_item_ty()`] for an example usage of this.
### Usage in Clippy
+
Clippy tries to use diagnostic items where possible and has developed some
wrapper and utility functions. Please also refer to its documentation when
using diagnostic items in Clippy. (See [*Common tools for writing
lints*][clippy-Common-tools-for-writing-lints].)
## Related issues
-This lists some related issues. These are probably only interesting to people
+
+These are probably only interesting to people
who really want to take a deep dive into the topic :)
* [rust#60966]: The Rust PR that introduced diagnostic items
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
index f28350e03..f456474c7 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/diagnostic-structs.md
@@ -17,45 +17,43 @@ shown below:
```rust,ignore
#[derive(SessionDiagnostic)]
-#[error(typeck::field_already_declared, code = "E0124")]
+#[diag(typeck::field_already_declared, code = "E0124")]
pub struct FieldAlreadyDeclared {
pub field_name: Ident,
#[primary_span]
#[label]
pub span: Span,
- #[label = "previous-decl-label"]
+ #[label(typeck::previous_decl_label)]
pub prev_span: Span,
}
```
`SessionDiagnostic` can only be applied to structs. Every `SessionDiagnostic`
-has to have one attribute applied to the struct itself: either `#[error(..)]`
-for defining errors, or `#[warning(..)]` for defining warnings.
+has to have one attribute, `#[diag(...)]`, applied to the struct itself.
If an error has an error code (e.g. "E0624"), then that can be specified using
the `code` sub-attribute. Specifying a `code` isn't mandatory, but if you are
porting a diagnostic that uses `DiagnosticBuilder` to use `SessionDiagnostic`
then you should keep the code if there was one.
-Both `#[error(..)]` and `#[warning(..)]` must provide a slug as the first
-positional argument (a path to an item in `rustc_errors::fluent::*`). A slug
-uniquely identifies the diagnostic and is also how the compiler knows what
-error message to emit (in the default locale of the compiler, or in the locale
-requested by the user). See [translation documentation](./translation.md) to
-learn more about how translatable error messages are written and how slug
-items are generated.
+`#[diag(..)]` must provide a slug as the first positional argument (a path to an
+item in `rustc_errors::fluent::*`). A slug uniquely identifies the diagnostic
+and is also how the compiler knows what error message to emit (in the default
+locale of the compiler, or in the locale requested by the user). See
+[translation documentation](./translation.md) to learn more about how
+translatable error messages are written and how slug items are generated.
In our example, the Fluent message for the "field already declared" diagnostic
looks like this:
```fluent
-typeck-field-already-declared =
+typeck_field_already_declared =
field `{$field_name}` is already declared
.label = field already declared
- .previous-decl-label = `{$field_name}` first declared here
+ .previous_decl_label = `{$field_name}` first declared here
```
-`typeck-field-already-declared` is the slug from our example and is followed
+`typeck_field_already_declared` is the slug from our example and is followed
by the diagnostic message.
Every field of the `SessionDiagnostic` which does not have an annotation is
@@ -75,10 +73,10 @@ type `Span`. Applying any of these attributes will create the corresponding
subdiagnostic with that `Span`. These attributes will look for their
diagnostic message in a Fluent attribute attached to the primary Fluent
message. In our example, `#[label]` will look for
-`typeck-field-already-declared.label` (which has the message "field already
+`typeck_field_already_declared.label` (which has the message "field already
declared"). If there is more than one subdiagnostic of the same type, then
these attributes can also take a value that is the attribute name to look for
-(e.g. `previous-decl-label` in our example).
+(e.g. `previous_decl_label` in our example).
Other types have special behavior when used in a `SessionDiagnostic` derive:
@@ -95,38 +93,35 @@ represent optional `#[note]`/`#[help]` subdiagnostics.
Suggestions can be emitted using one of four field attributes:
-- `#[suggestion(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_hidden(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_short(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_verbose(message = "...", code = "...", applicability = "...")]`
+- `#[suggestion(slug, code = "...", applicability = "...")]`
+- `#[suggestion_hidden(slug, code = "...", applicability = "...")]`
+- `#[suggestion_short(slug, code = "...", applicability = "...")]`
+- `#[suggestion_verbose(slug, code = "...", applicability = "...")]`
Suggestions must be applied on either a `Span` field or a `(Span,
-MachineApplicability)` field. Similarly to other field attributes, `message`
-specifies the Fluent attribute with the message and defaults to `.suggestion`.
-`code` specifies the code that should be suggested as a replacement and is a
-format string (e.g. `{field_name}` would be replaced by the value of the
-`field_name` field of the struct), not a Fluent identifier. `applicability` can
-be used to specify the applicability in the attribute, it cannot be used when
-the field's type contains an `Applicability`.
+MachineApplicability)` field. Similarly to other field attributes, the slug
+specifies the Fluent attribute with the message and defaults to the equivalent
+of `.suggestion`. `code` specifies the code that should be suggested as a
+replacement and is a format string (e.g. `{field_name}` would be replaced by
+the value of the `field_name` field of the struct), not a Fluent identifier.
+`applicability` can be used to specify the applicability in the attribute, it
+cannot be used when the field's type contains an `Applicability`.
In the end, the `SessionDiagnostic` derive will generate an implementation of
`SessionDiagnostic` that looks like the following:
```rust,ignore
-impl SessionDiagnostic for FieldAlreadyDeclared {
+impl SessionDiagnostic<'_> for FieldAlreadyDeclared {
fn into_diagnostic(self, sess: &'_ rustc_session::Session) -> DiagnosticBuilder<'_> {
- let mut diag = sess.struct_err_with_code(
- rustc_errors::DiagnosticMessage::fluent("typeck-field-already-declared"),
- rustc_errors::DiagnosticId::Error("E0124")
- );
+ let mut diag = sess.struct_err(rustc_errors::fluent::typeck::field_already_declared);
diag.set_span(self.span);
diag.span_label(
self.span,
- rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "label")
+ rustc_errors::fluent::typeck::label
);
diag.span_label(
self.prev_span,
- rustc_errors::DiagnosticMessage::fluent_attr("typeck-field-already-declared", "previous-decl-label")
+ rustc_errors::fluent::typeck::previous_decl_label
);
diag
}
@@ -146,12 +141,13 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
```
### Reference
-`#[derive(SessionDiagnostic)]` supports the following attributes:
+`#[derive(SessionDiagnostic)]` and `#[derive(LintDiagnostic)]` support the
+following attributes:
-- `#[error(slug, code = "...")]` or `#[warning(slug, code = "...")]`
+- `#[diag(slug, code = "...")]`
- _Applied to struct._
- _Mandatory_
- - Defines the struct to be representing an error or a warning.
+ - Defines the text and error code to be associated with the diagnostic.
- Slug (_Mandatory_)
- Uniquely identifies the diagnostic and corresponds to its Fluent message,
mandatory.
@@ -164,34 +160,48 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
- See [translation documentation](./translation.md).
- `code = "..."` (_Optional_)
- Specifies the error code.
-- `#[note]` or `#[note = "..."]` (_Optional_)
+- `#[note]` or `#[note(slug)]` (_Optional_)
- _Applied to struct or `Span`/`()` fields._
- Adds a note subdiagnostic.
- - Value is the Fluent attribute (relative to the Fluent message specified by
- `slug`) for the note's message
- - Defaults to `note`.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.note`.
- If applied to a `Span` field, creates a spanned note.
-- `#[help]` or `#[help = "..."]` (_Optional_)
+- `#[help]` or `#[help(slug)]` (_Optional_)
- _Applied to struct or `Span`/`()` fields._
- Adds a help subdiagnostic.
- - Value is the Fluent attribute (relative to the Fluent message specified by
- `slug`) for the help's message.
- - Defaults to `help`.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.help`.
- If applied to a `Span` field, creates a spanned help.
-- `#[label]` or `#[label = "..."]` (_Optional_)
+- `#[label]` or `#[label(slug)]` (_Optional_)
- _Applied to `Span` fields._
- Adds a label subdiagnostic.
- - Value is the Fluent attribute (relative to the Fluent message specified by
- `slug`) for the label's message.
- - Defaults to `label`.
-- `#[suggestion{,_hidden,_short,_verbose}(message = "...", code = "...", applicability = "...")]`
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.label`.
+- `#[warn_]` or `#[warn_(slug)]` (_Optional_)
+ - _Applied to `Span` fields._
+ - Adds a warning subdiagnostic.
+ - Value is a path to an item in `rustc_errors::fluent` for the note's
+ message.
+ - Defaults to equivalent of `.warn`.
+- `#[suggestion{,_hidden,_short,_verbose}(slug, code = "...", applicability = "...")]`
(_Optional_)
- _Applied to `(Span, MachineApplicability)` or `Span` fields._
- Adds a suggestion subdiagnostic.
- - `message = "..."` (_Mandatory_)
- - Value is the Fluent attribute (relative to the Fluent message specified
- by `slug`) for the suggestion's message.
- - Defaults to `suggestion`.
+ - Slug (_Mandatory_)
+ - A path to an item in `rustc_errors::fluent`. Always in a module starting
+ with a Fluent resource name (which is typically the name of the crate
+ that the diagnostic is from), e.g.
+ `rustc_errors::fluent::typeck::field_already_declared`
+ (`rustc_errors::fluent` is implicit in the attribute, so just
+ `typeck::field_already_declared`). Fluent attributes for all messages
+ exist as top-level items in that module (so `typeck_message.attr` is just
+ `typeck::attr`).
+ - See [translation documentation](./translation.md).
+ - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or
+ - `.suggestion` in Fluent).
- `code = "..."` (_Mandatory_)
- Value is a format string indicating the code to be suggested as a
replacement.
@@ -203,7 +213,7 @@ tcx.sess.emit_err(FieldAlreadyDeclared {
`#[derive(SessionSubdiagnostic)]`)._
- Adds the subdiagnostic represented by the subdiagnostic struct.
- `#[primary_span]` (_Optional_)
- - _Applied to `Span` fields._
+ - _Applied to `Span` fields on `SessionSubdiagnostic`s. Not used for `LintDiagnostic`s._
- Indicates the primary span of the diagnostic.
- `#[skip_arg]` (_Optional_)
- _Applied to any field._
@@ -258,9 +268,9 @@ In our example, the Fluent message for the "expected return type" label
looks like this:
```fluent
-typeck-expected-default-return-type = expected `()` because of default return type
+typeck_expected_default_return_type = expected `()` because of default return type
-typeck-expected-return-type = expected `{$expected}` because of return type
+typeck_expected_return_type = expected `{$expected}` because of return type
```
Using the `#[primary_span]` attribute on a field (with type `Span`) will denote
@@ -276,16 +286,17 @@ Like `SessionDiagnostic`, `SessionSubdiagnostic` supports `Option<T>` and
Suggestions can be emitted using one of four attributes on the type/variant:
-- `#[suggestion(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_hidden(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_short(message = "...", code = "...", applicability = "...")]`
-- `#[suggestion_verbose(message = "...", code = "...", applicability = "...")]`
+- `#[suggestion(..., code = "...", applicability = "...")]`
+- `#[suggestion_hidden(..., code = "...", applicability = "...")]`
+- `#[suggestion_short(..., code = "...", applicability = "...")]`
+- `#[suggestion_verbose(..., code = "...", applicability = "...")]`
Suggestions require `#[primary_span]` be set on a field and can have the
following sub-attributes:
-- `message` specifies the Fluent attribute with the message and defaults to
- `.suggestion`.
+- The first positional argument specifies the path to a item in
+ `rustc_errors::fluent` corresponding to the Fluent attribute with the message
+ and defaults to the equivalent of `.suggestion`.
- `code` specifies the code that should be suggested as a replacement and is a
format string (e.g. `{field_name}` would be replaced by the value of the
`field_name` field of the struct), not a Fluent identifier.
@@ -304,11 +315,11 @@ impl<'tcx> AddToDiagnostic for ExpectedReturnTypeLabel<'tcx> {
use rustc_errors::{Applicability, IntoDiagnosticArg};
match self {
ExpectedReturnTypeLabel::Unit { span } => {
- diag.span_label(span, DiagnosticMessage::fluent("typeck-expected-default-return-type"))
+ diag.span_label(span, rustc_errors::fluent::typeck::expected_default_return_type)
}
ExpectedReturnTypeLabel::Other { span, expected } => {
diag.set_arg("expected", expected);
- diag.span_label(span, DiagnosticMessage::fluent("typeck-expected-return-type"))
+ diag.span_label(span, rustc_errors::fluent::typeck::expected_return_type)
}
}
@@ -338,14 +349,22 @@ diagnostic struct.
(`rustc_errors::fluent` is implicit in the attribute, so just
`typeck::field_already_declared`).
- See [translation documentation](./translation.md).
-- `#[suggestion{,_hidden,_short,_verbose}(message = "...", code = "...", applicability = "...")]`
+- `#[suggestion{,_hidden,_short,_verbose}(slug, code = "...", applicability = "...")]`
- _Applied to struct or enum variant. Mutually exclusive with struct/enum variant attributes._
- _Mandatory_
- Defines the type to be representing a suggestion.
- - `message = "..."` (_Mandatory_)
- - Value is the Fluent attribute (relative to the Fluent message specified
- by `slug`) for the suggestion's message.
- - Defaults to `suggestion`.
+ - Slug (_Mandatory_)
+ - A path to an item in `rustc_errors::fluent`. Always in a module starting
+ with a Fluent resource name (which is typically the name of the crate
+ that the diagnostic is from), e.g.
+ `rustc_errors::fluent::typeck::field_already_declared`
+ (`rustc_errors::fluent` is implicit in the attribute, so just
+ `typeck::field_already_declared`). Fluent attributes for all messages
+ exist as top-level items in that module (so `typeck_message.attr` is just
+ `typeck::attr`).
+ - See [translation documentation](./translation.md).
+ - Defaults to `rustc_errors::fluent::_subdiag::suggestion` (or
+ - `.suggestion` in Fluent).
- `code = "..."` (_Mandatory_)
- Value is a format string indicating the code to be suggested as a
replacement.
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
index 39007f8d1..33d9646f6 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/lintstore.md
@@ -1,4 +1,5 @@
# Lints
+
This page documents some of the machinery around lint registration and how we
run lints in the compiler.
@@ -8,6 +9,7 @@ everything rotates. It's not available during the early parts of compilation
lints, which can only happen after plugin registration.
## Lints vs. lint passes
+
There are two parts to the linting mechanism within the compiler: lints and
lint passes. Unfortunately, a lot of the documentation we have refers to both
of these as just "lints."
@@ -15,11 +17,18 @@ of these as just "lints."
First, we have the lint declarations themselves: this is where the name and
default lint level and other metadata come from. These are normally defined by
way of the [`declare_lint!`] macro, which boils down to a static with type
-`&rustc_session::lint::Lint`.
+[`&rustc_lint_defs::Lint`].
+
+First, we have the lint declarations themselves,
+and this is where the name and default lint level and other metadata come from.
+These are normally defined by way of the [`declare_lint!`] macro,
+which boils down to a static with type [`&rustc_lint_defs::Lint`]
+(although this may change in the future,
+as the macro is somewhat unwieldy to add new fields to,
+like all macros).
-As of <!-- date: 2022-02 --> February 2022, we lint against direct declarations
-without the use of the macro today (although this may change in the future, as
-the macro is somewhat unwieldy to add new fields to, like all macros).
+As of <!-- date-check --> Aug 2022,
+we lint against direct declarations without the use of the macro.
Lint declarations don't carry any "state" - they are merely global identifiers
and descriptions of lints. We assert at runtime that they are not registered
@@ -34,8 +43,10 @@ lints are emitted as part of other work (e.g., type checking, etc.).
## Registration
### High-level overview
-In [`rustc_interface::register_plugins`] the [`LintStore`] is created and all
-lints are registered.
+
+In [`rustc_interface::register_plugins`],
+the [`LintStore`] is created,
+and all lints are registered.
There are four 'sources' of lints:
@@ -61,6 +72,7 @@ then invoke the lint pass methods. The lint pass methods take `&mut self` so
they can keep track of state internally.
#### Internal lints
+
These are lints used just by the compiler or plugins like `clippy`. They can be
found in `rustc_lint::internal`.
@@ -73,16 +85,20 @@ function which is called when constructing a new lint store inside
[`rustc_lint::new_lint_store`].
### Builtin Lints
-These are primarily described in two places: `rustc_session::lint::builtin` and
-`rustc_lint::builtin`. Often the first provides the definitions for the lints
-themselves, and the latter provides the lint pass definitions (and
-implementations), but this is not always true.
-The builtin lint registration happens in the [`rustc_lint::register_builtins`]
-function. Just like with internal lints, this happens inside of
-[`rustc_lint::new_lint_store`].
+These are primarily described in two places,
+`rustc_lint_defs::builtin` and `rustc_lint::builtin`.
+Often the first provides the definitions for the lints themselves,
+and the latter provides the lint pass definitions (and implementations),
+but this is not always true.
+
+The builtin lint registration happens in
+the [`rustc_lint::register_builtins`] function.
+Just like with internal lints,
+this happens inside of [`rustc_lint::new_lint_store`].
#### Plugin lints
+
This is one of the primary use cases remaining for plugins/drivers. Plugins are
given access to the mutable `LintStore` during registration (which happens
inside of [`rustc_interface::register_plugins`]) and they can call any
@@ -94,6 +110,7 @@ diagnostics and help text; otherwise plugin lints are mostly just as first
class as rustc builtin lints.
#### Driver lints
+
These are the lints provided by drivers via the `rustc_interface::Config`
[`register_lints`] field, which is a callback. Drivers should, if finding it
already set, call the function currently set within the callback they add. The
@@ -102,6 +119,7 @@ best way for drivers to get access to this is by overriding the
structure.
## Compiler lint passes are combined into one pass
+
Within the compiler, for performance reasons, we usually do not register dozens
of lint passes. Instead, we have a single lint pass of each variety (e.g.,
`BuiltinCombinedModuleLateLintPass`) which will internally call all of the
@@ -121,3 +139,4 @@ approach, it is beneficial to do so for performance reasons.
[`declare_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/macro.declare_lint.html
[`declare_tool_lint!`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/macro.declare_tool_lint.html
[`register_lints`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Config.html#structfield.register_lints
+[`&rustc_lint_defs::Lint`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_lint_defs/struct.Lint.html
diff --git a/src/doc/rustc-dev-guide/src/diagnostics/translation.md b/src/doc/rustc-dev-guide/src/diagnostics/translation.md
index 5c078ffb3..5bb37fbc2 100644
--- a/src/doc/rustc-dev-guide/src/diagnostics/translation.md
+++ b/src/doc/rustc-dev-guide/src/diagnostics/translation.md
@@ -32,23 +32,23 @@ Diagnostic messages are defined in Fluent resources. A combined set of Fluent
resources for a given locale (e.g. `en-US`) is known as Fluent bundle.
```fluent
-typeck-address-of-temporary-taken = cannot take address of a temporary
+typeck_address_of_temporary_taken = cannot take address of a temporary
```
-In the above example, `typeck-address-of-temporary-taken` is the identifier for
+In the above example, `typeck_address_of_temporary_taken` is the identifier for
a Fluent message and corresponds to the diagnostic message in English. Other
Fluent resources can be written which would correspond to a message in another
language. Each diagnostic therefore has at least one Fluent message.
```fluent
-typeck-address-of-temporary-taken = cannot take address of a temporary
+typeck_address_of_temporary_taken = cannot take address of a temporary
.label = temporary value
```
By convention, diagnostic messages for subdiagnostics are specified as
"attributes" on Fluent messages (additional related messages, denoted by the
`.<attribute-name>` syntax). In the above example, `label` is an attribute of
-`typeck-address-of-temporary-taken` which corresponds to the message for the
+`typeck_address_of_temporary_taken` which corresponds to the message for the
label added to this diagnostic.
Diagnostic messages often interpolate additional context into the message shown
@@ -56,7 +56,7 @@ to the user, such as the name of a type or of a variable. Additional context to
Fluent messages is provided as an "argument" to the diagnostic.
```fluent
-typeck-struct-expr-non-exhaustive =
+typeck_struct_expr_non_exhaustive =
cannot create non-exhaustive {$what} using struct expression
```
@@ -67,6 +67,13 @@ discussed in detail later).
You can consult the [Fluent] documentation for other usage examples of Fluent
and its syntax.
+### Guideline for message naming
+Usually, fluent uses `-` for separating words inside a message name. However,
+`_` is accepted by fluent as well. As `_` fits Rust's use cases better, due to
+the identifiers on the Rust side using `_` as well, inside rustc, `-` is not
+allowed for separating words, and instead `_` is recommended. The only exception
+is for leading `-`s, for message names like `-passes_see_issue`.
+
### Guidelines for writing translatable messages
For a message to be translatable into different languages, all of the
information required by any language must be provided to the diagnostic as an
@@ -106,10 +113,10 @@ fluent_messages! {
For example, given the following Fluent...
```fluent
-typeck-field-multiply-specified-in-initializer =
+typeck_field_multiply_specified_in_initializer =
field `{$ident}` specified more than once
.label = used more than once
- .label-previous-use = first use of `{$ident}`
+ .label_previous_use = first use of `{$ident}`
```
...then the `fluent_messages` macro will generate:
@@ -122,11 +129,11 @@ pub static DEFAULT_LOCALE_RESOURCES: &'static [&'static str] = &[
mod fluent_generated {
mod typeck {
pub const field_multiply_specified_in_initializer: DiagnosticMessage =
- DiagnosticMessage::new("typeck-field-multiply-specified-in-initializer");
+ DiagnosticMessage::new("typeck_field_multiply_specified_in_initializer");
pub const label: SubdiagnosticMessage =
SubdiagnosticMessage::attr("label");
pub const label_previous_use: SubdiagnosticMessage =
- SubdiagnosticMessage::attr("previous-use-label");
+ SubdiagnosticMessage::attr("previous_use_label");
}
}
```
@@ -217,7 +224,7 @@ returned by `Emitter::fluent_bundle`. This bundle is used preferentially when
translating messages, the fallback bundle is only used if the primary bundle is
missing a message or not provided.
-As of <!-- date: 2022-06 --> June 2022, there are no locale bundles
+As of <!-- date-check --> June 2022, there are no locale bundles
distributed with the compiler, but mechanisms are implemented for loading
bundles.