@@ -36,6 +36,20 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {
36
36
/// Usually it's nicer to provide more context for lint messages.
37
37
/// Be sure the output is understandable when you use this method.
38
38
///
39
+ /// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine
40
+ /// the lint level.
41
+ /// For the `span_lint` function, the node that was passed into the `LintPass::check_*` function is
42
+ /// used.
43
+ ///
44
+ /// If you're emitting the lint at the span of a different node than the one provided by the
45
+ /// `LintPass::check_*` function, consider using [`span_lint_hir`] instead.
46
+ /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
47
+ /// highlighted in the displayed warning.
48
+ ///
49
+ /// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
50
+ /// where you would expect it to.
51
+ /// If it doesn't, you likely need to use [`span_lint_hir`] instead.
52
+ ///
39
53
/// # Example
40
54
///
41
55
/// ```ignore
@@ -61,6 +75,20 @@ pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<Mult
61
75
///
62
76
/// If you change the signature, remember to update the internal lint `CollapsibleCalls`
63
77
///
78
+ /// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine
79
+ /// the lint level.
80
+ /// For the `span_lint_and_help` function, the node that was passed into the `LintPass::check_*`
81
+ /// function is used.
82
+ ///
83
+ /// If you're emitting the lint at the span of a different node than the one provided by the
84
+ /// `LintPass::check_*` function, consider using [`span_lint_hir_and_then`] instead.
85
+ /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
86
+ /// highlighted in the displayed warning.
87
+ ///
88
+ /// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
89
+ /// where you would expect it to.
90
+ /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
91
+ ///
64
92
/// # Example
65
93
///
66
94
/// ```text
@@ -99,6 +127,20 @@ pub fn span_lint_and_help<T: LintContext>(
99
127
///
100
128
/// If you change the signature, remember to update the internal lint `CollapsibleCalls`
101
129
///
130
+ /// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine
131
+ /// the lint level.
132
+ /// For the `span_lint_and_note` function, the node that was passed into the `LintPass::check_*`
133
+ /// function is used.
134
+ ///
135
+ /// If you're emitting the lint at the span of a different node than the one provided by the
136
+ /// `LintPass::check_*` function, consider using [`span_lint_hir_and_then`] instead.
137
+ /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
138
+ /// highlighted in the displayed warning.
139
+ ///
140
+ /// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
141
+ /// where you would expect it to.
142
+ /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
143
+ ///
102
144
/// # Example
103
145
///
104
146
/// ```text
@@ -139,6 +181,20 @@ pub fn span_lint_and_note<T: LintContext>(
139
181
///
140
182
/// If you need to customize your lint output a lot, use this function.
141
183
/// If you change the signature, remember to update the internal lint `CollapsibleCalls`
184
+ ///
185
+ /// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine
186
+ /// the lint level.
187
+ /// For the `span_lint_and_then` function, the node that was passed into the `LintPass::check_*`
188
+ /// function is used.
189
+ ///
190
+ /// If you're emitting the lint at the span of a different node than the one provided by the
191
+ /// `LintPass::check_*` function, consider using [`span_lint_hir_and_then`] instead.
192
+ /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
193
+ /// highlighted in the displayed warning.
194
+ ///
195
+ /// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
196
+ /// where you would expect it to.
197
+ /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
142
198
pub fn span_lint_and_then < C , S , F > ( cx : & C , lint : & ' static Lint , sp : S , msg : & str , f : F )
143
199
where
144
200
C : LintContext ,
@@ -152,13 +208,61 @@ where
152
208
} ) ;
153
209
}
154
210
211
+ /// Like [`span_lint`], but emits the lint at the node identified by the given `HirId`.
212
+ ///
213
+ /// This is in contrast to [`span_lint`], which always emits the lint at the node that was last
214
+ /// passed to the `LintPass::check_*` function.
215
+ ///
216
+ /// The `HirId` is used for checking lint level attributes and to fulfill lint expectations defined
217
+ /// via the `#[expect]` attribute.
218
+ ///
219
+ /// For example:
220
+ /// ```ignore
221
+ /// fn f() { /* <node_1> */
222
+ ///
223
+ /// #[allow(clippy::some_lint)]
224
+ /// let _x = /* <expr_1> */;
225
+ /// }
226
+ /// ```
227
+ /// If `some_lint` does its analysis in `LintPass::check_fn` (at `<node_1>`) and emits a lint at
228
+ /// `<expr_1>` using [`span_lint`], then allowing the lint at `<expr_1>` as attempted in the snippet
229
+ /// will not work!
230
+ /// Even though that is where the warning points at, which would be confusing to users.
231
+ ///
232
+ /// Instead, use this function and also pass the `HirId` of `<expr_1>`, which will let
233
+ /// the compiler check lint level attributes at the place of the expression and
234
+ /// the `#[allow]` will work.
155
235
pub fn span_lint_hir ( cx : & LateContext < ' _ > , lint : & ' static Lint , hir_id : HirId , sp : Span , msg : & str ) {
156
236
#[ expect( clippy:: disallowed_methods) ]
157
237
cx. tcx . node_span_lint ( lint, hir_id, sp, msg. to_string ( ) , |diag| {
158
238
docs_link ( diag, lint) ;
159
239
} ) ;
160
240
}
161
241
242
+ /// Like [`span_lint_and_then`], but emits the lint at the node identified by the given `HirId`.
243
+ ///
244
+ /// This is in contrast to [`span_lint_and_then`], which always emits the lint at the node that was
245
+ /// last passed to the `LintPass::check_*` function.
246
+ ///
247
+ /// The `HirId` is used for checking lint level attributes and to fulfill lint expectations defined
248
+ /// via the `#[expect]` attribute.
249
+ ///
250
+ /// For example:
251
+ /// ```ignore
252
+ /// fn f() { /* <node_1> */
253
+ ///
254
+ /// #[allow(clippy::some_lint)]
255
+ /// let _x = /* <expr_1> */;
256
+ /// }
257
+ /// ```
258
+ /// If `some_lint` does its analysis in `LintPass::check_fn` (at `<node_1>`) and emits a lint at
259
+ /// `<expr_1>` using [`span_lint`], then allowing the lint at `<expr_1>` as attempted in the snippet
260
+ /// will not work!
261
+ /// Even though that is where the warning points at, which would be confusing to users.
262
+ ///
263
+ /// Instead, use this function and also pass the `HirId` of `<expr_1>`, which will let
264
+ /// the compiler check lint level attributes at the place of the expression and
265
+ /// the `#[allow]` will work.
162
266
pub fn span_lint_hir_and_then (
163
267
cx : & LateContext < ' _ > ,
164
268
lint : & ' static Lint ,
@@ -182,6 +286,20 @@ pub fn span_lint_hir_and_then(
182
286
///
183
287
/// If you change the signature, remember to update the internal lint `CollapsibleCalls`
184
288
///
289
+ /// NOTE: Lint emissions are always bound to a node in the HIR, which is used to determine
290
+ /// the lint level.
291
+ /// For the `span_lint_and_sugg` function, the node that was passed into the `LintPass::check_*`
292
+ /// function is used.
293
+ ///
294
+ /// If you're emitting the lint at the span of a different node than the one provided by the
295
+ /// `LintPass::check_*` function, consider using [`span_lint_hir_and_then`] instead.
296
+ /// This is needed for `#[allow]` and `#[expect]` attributes to work on the node
297
+ /// highlighted in the displayed warning.
298
+ ///
299
+ /// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
300
+ /// where you would expect it to.
301
+ /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
302
+ ///
185
303
/// # Example
186
304
///
187
305
/// ```text
0 commit comments