@@ -15,8 +15,8 @@ For any lint check `C`:
1515
1616* ` #[allow(C)] ` overrides the check for ` C ` so that violations will go
1717 unreported,
18- * ` #[expect(c )] ` suppresses all lint emissions of ` C ` , but will issue
19- a warning, if the lint wasn't emitted in the expected scope.
18+ * ` #[expect(C )] ` suppresses all lint emissions of ` C ` , but will issue
19+ a warning if the lint wasn't emitted in the expected scope.
2020* ` #[warn(C)] ` warns about violations of ` C ` but continues compilation.
2121* ` #[deny(C)] ` signals an error after encountering a violation of ` C ` ,
2222* ` #[forbid(C)] ` is the same as ` deny(C) ` , but also forbids changing the lint
@@ -68,8 +68,8 @@ pub mod m2{
6868}
6969```
7070
71- This example shows how one can use ` forbid ` to disallow uses of ` allow ` for
72- that lint check:
71+ This example shows how one can use ` forbid ` to disallow uses of ` allow ` or
72+ ` expect ` for that lint check:
7373
7474``` rust,compile_fail
7575#[forbid(missing_docs)]
@@ -85,14 +85,33 @@ pub mod m3 {
8585> [ command-line] [ rustc-lint-cli ] , and also supports [ setting
8686> caps] [ rustc-lint-caps ] on the lints that are reported.
8787
88+ ### Lint Reasons
89+
8890All lint attributes support an additional ` reason ` parameter, to give context why
8991a certain attribute was added. This reason will be displayed as part of the lint
90- message, if the lint is emitted at the defined level.
92+ message if the lint is emitted at the defined level.
93+
94+ ``` rust,edition2015
95+ // `keyword_idents` is allowed by default. Here we deny it to
96+ // avoid migration of identifies when we update the edition.
97+ #![deny(
98+ keyword_idents,
99+ reason = "we want to avoid these idents to be future compatible"
100+ )]
101+
102+ // This name was allowed in Rust's 2015 edition. We still aim to avoid
103+ // this to be future compatible and not confuse end users.
104+ fn dyn() {}
105+ ```
106+
107+ Here we have another example, where the lint is allowed with a reason:
91108
92109``` rust
93110use std :: path :: PathBuf ;
94111
95112pub fn get_path () -> PathBuf {
113+ // Using `reason` with an `allow` attribute has no effect other than to
114+ // provide documentation to the reader.
96115 #[allow(unused_mut, reason = " this is only modified on some platforms" )]
97116 let mut file_name = PathBuf :: from (" git" );
98117
@@ -103,37 +122,86 @@ pub fn get_path() -> PathBuf {
103122}
104123```
105124
106- ### Lint expectations
125+ ### The ` expect ` attribute
107126
108- With the ` #[ expect] ` attributes lints can be expected in a certain scope. If
109- this expectation is not fulfilled a new warning is emitted to the user. The
110- lint levels can be overridden with other lint attributes as usual .
127+ The * ` expect ` attribute * is used to mark that a particular lint must be triggered
128+ within its scope. If this expectation is not fulfilled a new warning is emitted to
129+ the user .
111130
112131``` rust
113- #[warn(missing_docs)]
114- pub mod m2 {
115- #[expect(missing_docs)]
116- pub mod nested {
117- // This missing documentation fulfills the expectation above
118- pub fn undocumented_one () -> i32 { 1 }
132+ fn main () {
133+ // This `expect` attribute creates an expectation, that the `unused_variables`
134+ // will be triggered by the following statement. This expectation will not be
135+ // fulfilled, since the `question` variable is used by the `println!` macro.
136+ #[expect(unused_variables)]
137+ let question = " who lives in a pineapple under the sea?" ;
138+ println! (" {question}" );
139+
140+ // This `expect` attribute creates an expectation that will be fulfilled, since
141+ // the `answer` variable is never used. It will therefore trigger the
142+ // `unused_variables` lint which will be suppressed by the expectation and fullfil
143+ // it as well.
144+ #[expect(unused_variables)]
145+ let answer = " SpongeBob SquarePants!" ;
146+ }
147+ ```
119148
120- // Missing documentation signals a warning here, despite the expectation
121- // above. This emission would not fulfill the expectation
122- #[warn(missing_docs)]
123- pub fn undocumented_two () -> i32 { 2 }
124- }
149+ The lint expectation is only fulfilled by lint emissions which have been suppressed by
150+ the ` expect ` attribute. If the lint level is modified in the scope with other level
151+ attributes like ` warn ` or ` deny ` , the lint will be emitted at the defined level and not
152+ satisdy the expectation. Lint suppressions via ` allow ` or ` expect ` attributes inside the
153+ scope will also not fulfill the expectation.
125154
126- #[expect(missing_docs)]
127- /// This comment explains something cool about the function. The
128- /// expectation will not be fulfilled and in turn issue a warning.
129- pub fn undocumented_too () -> i32 { 3 }
155+ ``` rust
156+ #[expect(unused_variables)]
157+ fn select_song () {
158+ // This will emit the `unused_variables` lint at the warn level
159+ // as defined by the `warn` attribute. This will not fulfill the
160+ // expectation above the function.
161+ #[warn(unused_variables)]
162+ let song_name = " Crab Rave" ;
163+
164+ // The `allow` attribute suppresses the lint emission. This will not
165+ // fulfill the expectation as it has been suppressed by the `allow`
166+ // attribute and not the `expect` attribute above the function.
167+ #[allow(unused_variables)]
168+ let song_creator = " Noisestorm" ;
169+
170+ // This `expect` attribute will suppress the `unused_variables` lint emission
171+ // at the variable. The `expect` attribute above the function will still not
172+ // be fulfilled, since this lint emission has been suppressed by the local
173+ // expect attribute.
174+ #[expect(unused_variables)]
175+ let song_version = " Monstercat Release" ;
176+ }
177+ ```
178+
179+ If the ` expect ` attribute contains several lints, each one is expected separatly. For a
180+ lint group it's enough if one lint inside the group has been emitted:
181+
182+ ``` rust
183+ // This expectation will be fulfilled by the unused value inside the function
184+ // since the emitted `unused_variables` lint is inside the `unused` lint group.
185+ #[expect(unused)]
186+ pub fn thoughts () {
187+ let unused = " I'm running out of examples" ;
188+ }
189+
190+ pub fn another_example () {
191+ // This attribute creates two lint expectations. The `unused_mut` lint will be
192+ // suppressed and with that fulfill the first expectation. The `unused_variables`
193+ // won't be emitted, since the variable is used. That expectation will therefore
194+ // not be satisfied, and a warning will be emitted.
195+ #[expect(unused_mut, unused_variables)]
196+ let mut link = " https://www.rust-lang.org/" ;
197+
198+ println! (" Welcome to our community: {link}" );
130199}
131200```
132201
133- > Note: Lint expectations have been proposed in [ RFC 2383] . It was not defined
134- > how expectations of the expectation lint should be handled. The rustc
135- > implementation currently doesn't allow the expextation of the
136- > ` unfulfilled_lint_expectation ` lint. This can change in the future.
202+ > Note: The behavior of ` #[expect(unfulfilled_lint_expectations)] ` is currently
203+ > defined to always generate the ` unfulfilled_lint_expectations ` lint. This may
204+ > change in the future.
137205
138206### Lint groups
139207
0 commit comments