Skip to content

Commit e7ee98d

Browse files
committed
Do not lint unsafe code coming from external macros
1 parent 24e16f9 commit e7ee98d

File tree

3 files changed

+103
-1
lines changed

3 files changed

+103
-1
lines changed

clippy_lints/src/multiple_unsafe_ops_per_block.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ impl<'tcx> Visitor<'tcx> for UnsafeExprCollector<'tcx> {
119119
type NestedFilter = nested_filter::OnlyBodies;
120120

121121
fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
122+
if expr.span.in_external_macro(self.tcx.sess.source_map()) {
123+
// Check the content of the expanded code to still catch the unsafe
124+
// operation passed as macro arguments.
125+
return walk_expr(self, expr);
126+
}
127+
122128
match expr.kind {
123129
// The `await` itself will desugar to two unsafe calls, but we should ignore those.
124130
// Instead, check the expression that is `await`ed

tests/ui/multiple_unsafe_ops_per_block.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -312,4 +312,38 @@ fn check_closures() {
312312
}
313313
}
314314

315+
fn issue16116() {
316+
unsafe fn foo() -> u32 {
317+
0
318+
}
319+
320+
unsafe {
321+
// Do not lint even though `format!` expansion
322+
// contains unsafe calls.
323+
let _ = format!("{}", foo());
324+
}
325+
326+
unsafe {
327+
//~^ multiple_unsafe_ops_per_block
328+
let _ = format!("{}", foo());
329+
let _ = format!("{}", foo());
330+
}
331+
332+
unsafe {
333+
// Do not lint: only one `assert!()` argument is unsafe
334+
assert!(foo() == 0, "{}", 1 + 2);
335+
}
336+
337+
unsafe {
338+
//~^ multiple_unsafe_ops_per_block
339+
assert!(foo() == 0, "{}", 1 + 2);
340+
assert!(foo() == 0, "{}", 1 + 2);
341+
}
342+
343+
unsafe {
344+
//~^ multiple_unsafe_ops_per_block
345+
assert!(foo() == 0, "{}", foo());
346+
}
347+
}
348+
315349
fn main() {}

tests/ui/multiple_unsafe_ops_per_block.stderr

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -359,5 +359,67 @@ note: unsafe function call occurs here
359359
LL | apply(|| f(0));
360360
| ^^^^
361361

362-
error: aborting due to 16 previous errors
362+
error: this `unsafe` block contains 2 unsafe operations, expected only one
363+
--> tests/ui/multiple_unsafe_ops_per_block.rs:326:5
364+
|
365+
LL | / unsafe {
366+
LL | |
367+
LL | | let _ = format!("{}", foo());
368+
LL | | let _ = format!("{}", foo());
369+
LL | | }
370+
| |_____^
371+
|
372+
note: unsafe function call occurs here
373+
--> tests/ui/multiple_unsafe_ops_per_block.rs:328:31
374+
|
375+
LL | let _ = format!("{}", foo());
376+
| ^^^^^
377+
note: unsafe function call occurs here
378+
--> tests/ui/multiple_unsafe_ops_per_block.rs:329:31
379+
|
380+
LL | let _ = format!("{}", foo());
381+
| ^^^^^
382+
383+
error: this `unsafe` block contains 2 unsafe operations, expected only one
384+
--> tests/ui/multiple_unsafe_ops_per_block.rs:337:5
385+
|
386+
LL | / unsafe {
387+
LL | |
388+
LL | | assert!(foo() == 0, "{}", 1 + 2);
389+
LL | | assert!(foo() == 0, "{}", 1 + 2);
390+
LL | | }
391+
| |_____^
392+
|
393+
note: unsafe function call occurs here
394+
--> tests/ui/multiple_unsafe_ops_per_block.rs:339:17
395+
|
396+
LL | assert!(foo() == 0, "{}", 1 + 2);
397+
| ^^^^^
398+
note: unsafe function call occurs here
399+
--> tests/ui/multiple_unsafe_ops_per_block.rs:340:17
400+
|
401+
LL | assert!(foo() == 0, "{}", 1 + 2);
402+
| ^^^^^
403+
404+
error: this `unsafe` block contains 2 unsafe operations, expected only one
405+
--> tests/ui/multiple_unsafe_ops_per_block.rs:343:5
406+
|
407+
LL | / unsafe {
408+
LL | |
409+
LL | | assert!(foo() == 0, "{}", foo());
410+
LL | | }
411+
| |_____^
412+
|
413+
note: unsafe function call occurs here
414+
--> tests/ui/multiple_unsafe_ops_per_block.rs:345:17
415+
|
416+
LL | assert!(foo() == 0, "{}", foo());
417+
| ^^^^^
418+
note: unsafe function call occurs here
419+
--> tests/ui/multiple_unsafe_ops_per_block.rs:345:35
420+
|
421+
LL | assert!(foo() == 0, "{}", foo());
422+
| ^^^^^
423+
424+
error: aborting due to 19 previous errors
363425

0 commit comments

Comments
 (0)