You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: text/3366-diagnostic-attribute-namespace.md
+20-22Lines changed: 20 additions & 22 deletions
Original file line number
Diff line number
Diff line change
@@ -69,48 +69,41 @@ I expect the new attributes to be documented on the existing [Diagnostics](https
69
69
70
70
## The `#[diagnostic]` attribute namespace
71
71
72
-
This RFC proposes to introduce a new `#[diagnostic]` attribute namespace. This namespace is supposed to contain different attributes, which allow users to hint the compiler to emit specific error messages in certain cases like type mismatches, unsatisfied trait bounds or similar situations. By collecting such attributes in a common namespace it is easier for users to find useful attributes and it is easier for the language team to establish a set of common rules for these attributes.
72
+
This RFC proposes to introduce a new `#[diagnostic]` attribute namespace. This namespace is supposed to contain different attributes, which allow users to hint the compiler to emit specific diagnostic messages in certain cases like type mismatches, unsatisfied trait bounds or similar situations. By collecting such attributes in a common namespace it is easier for users to find useful attributes and it is easier for the language team to establish a set of common rules for these attributes.
73
73
74
74
Attributes in this namespace are generally expected to be formed like:
75
75
```rust
76
76
#[diagnostic::attribute(option)]
77
77
```
78
-
where several `option` entries can appear in the same attribute. `option` is expected to be a valid attribute argument in this position. Attributes in this namespace are versioned. Any incompatible change to an existing stable attribute in this namespace requires bumping the version of the diagnostic attribute namespace. Crates using these attributes must specify the expected version of the diagnostic namespace via a `#![diagnostic::v{version_number}]` crate top-level attribute. If multiple such attributes are present the compiler will choose the highest version number and ignore the rest. The compiler is encouraged to provide a lint for outdated versions of the diagnostic attribute namespace. This mechanism exists so that a third party crate can provide a shim implementation of the corresponding attributes to translate between different versions of the diagnostic attribute namespace on different rust versions.
78
+
where several `option` entries can appear in the same attribute. `option` is expected to be a valid attribute argument in this position.
79
79
80
80
Any attribute in this namespace may:
81
81
82
-
* Hint the compiler to emit a specific error message in a specific situation
83
-
* Only affect the messages emitted by a compiler in case of a failed compilation
82
+
* Hint the compiler to emit a specific diagnostic message in a specific situation
83
+
* Only affect the messages emitted by a compiler
84
84
85
85
Any attribute in this namespace is not allowed to:
86
86
87
-
* Change the result of the compilation, which means applying such an attribute should never cause an error as long as they are syntactically valid
88
-
*pass-through information from the source of the diagnostic in a way that users can rely on. E.g. Such an attribute should not allow users to keep the compilation successful and dump information about `extern` blocks to generate C header files
87
+
* Change the result of the compilation, which means applying such an attribute should never cause a compilation error as long as they are syntactically valid
88
+
*Pass-through information from the source of the diagnostic in a way that users can rely on. E.g. Such an attribute should not allow users to keep the compilation successful and dump information about `extern` blocks to generate C header files
89
89
90
90
The compiler is allowed to:
91
91
92
92
* Ignore the hints provided by:
93
93
+ A specific attribute
94
94
+ A specific option
95
-
* Change the set of supported attributes and options at any time
96
-
* Provide warning lints for malformed or otherwise not accepted attributes
95
+
* Change the support for a specific attribute or option at any time
97
96
98
97
The compiler must not:
99
98
100
-
* Change the semantic of an attribute or option, these kind of change requires a bump of the diagnostic attribute space version number
101
-
* Emit an hard error on malformed attribute, although emitting lints is fine
99
+
* Change the semantic of an attribute or option
100
+
* Emit an hard error on malformed attribute
102
101
103
-
Adding a new attribute or option to the `#[diagnostic]` namespace is a decision of the compiler team. The envisioned procedure for this is as following:
102
+
The compiler should:
104
103
105
-
1. The new attribute lands on nightly without a feature gate. It gets ignored on stable/beta until its explicitly activated there.
106
-
2. The time as nightly only attribute is used to verify that:
107
-
* The attribute solves a real problem
108
-
* The implemented syntax matches the expectations
109
-
3. To enable a certain attribute in stable release the following steps are required:
110
-
* The attribute is documented in the rust reference
111
-
* T-lang is informed
112
-
* T-compiler performs a FCP, where a simple majority (>50%) accepts the attribute
113
-
104
+
* Emit implement a warn-by-default lint for unrecognised attributes or options
105
+
106
+
Adding a new attribute or option to the `#[diagnostic]` namespace is for now a decision of the language team. The language team can delegate these decisions partially or completely to a different team without requiring a new RFC.
114
107
115
108
## The `#[diagnostic::on_unimplemented]` attribute
116
109
@@ -128,13 +121,13 @@ trait MyIterator<A> {
128
121
```
129
122
130
123
131
-
Each of the options `message`, `label` and `note` are optional. They are separated by comma. The trailing comma is optional. Specifying any of these options hints the compiler to replace the normally emitted part of the error message with the provided string. At least one of these options needs to exist. Each option can appear at most once. The error message can include type information for the `Self` type or any generic type by using `{Self}` or `{A}` (where `A` refers to the generic type name in the definition). These placeholders are replaced by the actual type name.
124
+
Each of the options `message`, `label` and `note` are optional. They are separated by comma. The trailing comma is optional. Specifying any of these options hints the compiler to replace the normally emitted part of the error message with the provided string. At least one of these options needs to exist. Each option can appear at most once. These options can include type information for the `Self` type or any generic type by using `{Self}` or `{A}` (where `A` refers to the generic type name in the definition). These placeholders are replaced by the compiler with the actual type name.
132
125
133
126
In addition the `on_unimplemented` attribute provides mechanisms to specify for which exact types a certain message should be emitted via an `if()` option. It accepts a set of filter options. A filter option consists of the generic parameter name from the trait definition and a type path against which the parameter should be checked. This type path could either be a fully qualified path or refer to any type in the current scope. As a special generic parameter name `Self` is added to refer to the `Self` type of the trait implementation. A filter option evaluates to `true` if the corresponding generic parameter in the trait definition matches the specified type. The provided `message`/`note`/`label` options are only emitted if the filter operation evaluates to `true`.
134
127
135
128
The `any` and `all` options allow to combine multiple filter options. The `any` option matches if one of the supplied filter options evaluates to `true`, the `all` option requires that all supplied filter options evaluate to true. `not` allows to negate a given filter option. It evaluates to `true` if the inner filter option evaluates to `false`. These options can be nested to construct complex filters.
136
129
137
-
The `on_unimplemented` attribute can be applied multiple times to the same trait definition. Multiple attributes are evaluated in order. The first matching instance for each of the `message`/`label`/`note` options is emitted. The compiler may lint against ignored variants as this is the case for `match` arms for example.
130
+
The `on_unimplemented` attribute can be applied multiple times to the same trait definition. Multiple attributes are evaluated in order. The first matching instance for each of the `message`/`label`/`note` options is emitted. The compiler should provide a warn-by-default lint for ignored variants as this is the case for `match` arms.
138
131
```rust
139
132
#[diagnostic::on_unimplemented(
140
133
if(Self= std::string::String),
@@ -225,6 +218,11 @@ Clarify the procedure of various potential changes prior stabilisation of the at
225
218
# Future possibilities
226
219
[future-possibilities]: #future-possibilities
227
220
221
+
* Add a versioning scheme
222
+
+ For specific attributes
223
+
+ For the namespace
224
+
+ Based on editions
225
+
+ Custom versioning scheme
228
226
* More attributes like `#[diagnostics::on_type_error]`
229
227
* Extend the `#[diagnostics::on_unimplemented]` attribute to incorporate the semantics of `#[do_not_recommend]` or
230
228
provide a distinct `#[diagnostics::do_not_recommend]` attribute
0 commit comments