@@ -7,17 +7,20 @@ messages during compilation.
7
7
8
8
A lint check names a potentially undesirable coding pattern, such as
9
9
unreachable code or omitted documentation. The lint attributes ` allow ` ,
10
- ` warn ` , ` deny ` , and ` forbid ` use the [ _ MetaListPaths_ ] syntax to specify a
11
- list of lint names to change the lint level for the entity to which the
12
- attribute applies.
10
+ ` expect ` , ` warn ` , ` deny ` , and ` forbid ` use the [ _ MetaListPaths_ ] syntax
11
+ to specify a list of lint names to change the lint level for the entity
12
+ to which the attribute applies.
13
13
14
14
For any lint check ` C ` :
15
15
16
- * ` allow(C) ` overrides the check for ` C ` so that violations will go
17
- unreported,
18
- * ` warn(C) ` warns about violations of ` C ` but continues compilation.
19
- * ` deny(C) ` signals an error after encountering a violation of ` C ` ,
20
- * ` forbid(C) ` is the same as ` deny(C) ` , but also forbids changing the lint
16
+ * ` #[allow(C)] ` overrides the check for ` C ` so that violations will go
17
+ unreported.
18
+ * ` #[expect(C)] ` indicates that lint ` C ` is expected to be emitted. The
19
+ attribute will suppress the emission of ` C ` or issue a warning, if the
20
+ expectation is unfulfilled.
21
+ * ` #[warn(C)] ` warns about violations of ` C ` but continues compilation.
22
+ * ` #[deny(C)] ` signals an error after encountering a violation of ` C ` ,
23
+ * ` #[forbid(C)] ` is the same as ` deny(C) ` , but also forbids changing the lint
21
24
level afterwards,
22
25
23
26
> Note: The lint checks supported by ` rustc ` can be found via ` rustc -W help ` ,
@@ -66,8 +69,8 @@ pub mod m2 {
66
69
}
67
70
```
68
71
69
- This example shows how one can use ` forbid ` to disallow uses of ` allow ` for
70
- that lint check:
72
+ This example shows how one can use ` forbid ` to disallow uses of ` allow ` or
73
+ ` expect ` for that lint check:
71
74
72
75
``` rust,compile_fail
73
76
#[forbid(missing_docs)]
@@ -83,6 +86,124 @@ pub mod m3 {
83
86
> [ command-line] [ rustc-lint-cli ] , and also supports [ setting
84
87
> caps] [ rustc-lint-caps ] on the lints that are reported.
85
88
89
+ ### Lint Reasons
90
+
91
+ All lint attributes support an additional ` reason ` parameter, to give context why
92
+ a certain attribute was added. This reason will be displayed as part of the lint
93
+ message if the lint is emitted at the defined level.
94
+
95
+ ``` rust,edition2015,compile_fail
96
+ // `keyword_idents` is allowed by default. Here we deny it to
97
+ // avoid migration of identifiers when we update the edition.
98
+ #![deny(
99
+ keyword_idents,
100
+ reason = "we want to avoid these idents to be future compatible"
101
+ )]
102
+
103
+ // This name was allowed in Rust's 2015 edition. We still aim to avoid
104
+ // this to be future compatible and not confuse end users.
105
+ fn dyn() {}
106
+ ```
107
+
108
+ Here is another example, where the lint is allowed with a reason:
109
+
110
+ ``` rust
111
+ use std :: path :: PathBuf ;
112
+
113
+ pub fn get_path () -> PathBuf {
114
+ // The `reason` parameter on `allow` attributes acts as documentation for the reader.
115
+ #[allow(unused_mut, reason = " this is only modified on some platforms" )]
116
+ let mut file_name = PathBuf :: from (" git" );
117
+
118
+ #[cfg(target_os = " windows" )]
119
+ file_name . set_extension (" exe" );
120
+
121
+ file_name
122
+ }
123
+ ```
124
+
125
+ ### The ` #[expect] ` attribute
126
+
127
+ The ` #[expect(C)] ` attribute creates a lint expectation for lint ` C ` . The
128
+ expectation will be fulfilled, if a ` #[warn(C)] ` attribute at the same location
129
+ would result in a lint emission. If the expectation is unfulfilled, because
130
+ lint ` C ` would not be emitted, the ` unfulfilled_lint_expectations ` lint will
131
+ be emitted at the attribute.
132
+
133
+ ``` rust
134
+ fn main () {
135
+ // This `#[expect]` attribute creates a lint expectation, that the `unused_variables`
136
+ // lint would be emitted by the following statement. This expectation is
137
+ // unfulfilled, since the `question` variable is used by the `println!` macro.
138
+ // Therefore, the `unfulfilled_lint_expectations` lint will be emitted at the
139
+ // attribute.
140
+ #[expect(unused_variables)]
141
+ let question = " who lives in a pineapple under the sea?" ;
142
+ println! (" {question}" );
143
+
144
+ // This `#[expect]` attribute creates a lint expectation that will be fulfilled, since
145
+ // the `answer` variable is never used. The `unused_variables` lint, that would usually
146
+ // be emitted, is suppressed. No warning will be issued for the statement or attribute.
147
+ #[expect(unused_variables)]
148
+ let answer = " SpongeBob SquarePants!" ;
149
+ }
150
+ ```
151
+
152
+ The lint expectation is only fulfilled by lint emissions which have been suppressed by
153
+ the ` expect ` attribute. If the lint level is modified in the scope with other level
154
+ attributes like ` allow ` or ` warn ` , the lint emission will be handled accordingly and the
155
+ expectation will remain unfulfilled.
156
+
157
+ ``` rust
158
+ #[expect(unused_variables)]
159
+ fn select_song () {
160
+ // This will emit the `unused_variables` lint at the warn level
161
+ // as defined by the `warn` attribute. This will not fulfill the
162
+ // expectation above the function.
163
+ #[warn(unused_variables)]
164
+ let song_name = " Crab Rave" ;
165
+
166
+ // The `allow` attribute suppresses the lint emission. This will not
167
+ // fulfill the expectation as it has been suppressed by the `allow`
168
+ // attribute and not the `expect` attribute above the function.
169
+ #[allow(unused_variables)]
170
+ let song_creator = " Noisestorm" ;
171
+
172
+ // This `expect` attribute will suppress the `unused_variables` lint emission
173
+ // at the variable. The `expect` attribute above the function will still not
174
+ // be fulfilled, since this lint emission has been suppressed by the local
175
+ // expect attribute.
176
+ #[expect(unused_variables)]
177
+ let song_version = " Monstercat Release" ;
178
+ }
179
+ ```
180
+
181
+ If the ` expect ` attribute contains several lints, each one is expected separately. For a
182
+ lint group it's enough if one lint inside the group has been emitted:
183
+
184
+ ``` rust
185
+ // This expectation will be fulfilled by the unused value inside the function
186
+ // since the emitted `unused_variables` lint is inside the `unused` lint group.
187
+ #[expect(unused)]
188
+ pub fn thoughts () {
189
+ let unused = " I'm running out of examples" ;
190
+ }
191
+
192
+ pub fn another_example () {
193
+ // This attribute creates two lint expectations. The `unused_mut` lint will be
194
+ // suppressed and with that fulfill the first expectation. The `unused_variables`
195
+ // wouldn't be emitted, since the variable is used. That expectation will therefore
196
+ // be unsatisfied, and a warning will be emitted.
197
+ #[expect(unused_mut, unused_variables)]
198
+ let mut link = " https://www.rust-lang.org/" ;
199
+
200
+ println! (" Welcome to our community: {link}" );
201
+ }
202
+ ```
203
+
204
+ > Note: The behavior of ` #[expect(unfulfilled_lint_expectations)] ` is currently
205
+ > defined to always generate the ` unfulfilled_lint_expectations ` lint.
206
+
86
207
### Lint groups
87
208
88
209
Lints may be organized into named groups so that the level of related lints
0 commit comments