Skip to content

Commit 30b3336

Browse files
committed
Don't lint undocumented_unsafe_blocks on bad proc-macro spans.
1 parent 65f96e2 commit 30b3336

File tree

4 files changed

+55
-17
lines changed

4 files changed

+55
-17
lines changed

clippy_lints/src/undocumented_unsafe_blocks.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
4848
if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
4949
&& !in_external_macro(cx.tcx.sess, block.span)
5050
&& !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
51+
&& !is_unsafe_from_proc_macro(cx, block)
5152
&& !block_has_safety_comment(cx, block)
5253
{
5354
let source_map = cx.tcx.sess.source_map();
@@ -69,6 +70,17 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
6970
}
7071
}
7172

73+
fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
74+
let source_map = cx.sess().source_map();
75+
let file_pos = source_map.lookup_byte_offset(block.span.lo());
76+
file_pos
77+
.sf
78+
.src
79+
.as_deref()
80+
.and_then(|src| src.get(file_pos.pos.to_usize()..))
81+
.map_or(true, |src| !src.starts_with("unsafe"))
82+
}
83+
7284
/// Checks if the lines immediately preceding the block contain a safety comment.
7385
fn block_has_safety_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
7486
// This intentionally ignores text before the start of a function so something like:
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// compile-flags: --emit=link
2+
// no-prefer-dynamic
3+
4+
#![crate_type = "proc-macro"]
5+
6+
extern crate proc_macro;
7+
8+
use proc_macro::{Delimiter, Group, Ident, TokenStream, TokenTree};
9+
10+
#[proc_macro]
11+
pub fn unsafe_block(input: TokenStream) -> TokenStream {
12+
let span = input.into_iter().next().unwrap().span();
13+
TokenStream::from_iter([TokenTree::Ident(Ident::new("unsafe", span)), {
14+
let mut group = Group::new(Delimiter::Brace, TokenStream::new());
15+
group.set_span(span);
16+
TokenTree::Group(group)
17+
}])
18+
}

tests/ui/undocumented_unsafe_blocks.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
// aux-build:proc_macro_unsafe.rs
2+
13
#![warn(clippy::undocumented_unsafe_blocks)]
24

5+
extern crate proc_macro_unsafe;
6+
37
// Valid comments
48

59
fn nested_local() {
@@ -241,6 +245,10 @@ fn in_multiline_macro_call(x: *const u32) {
241245
);
242246
}
243247

248+
fn from_proc_macro() {
249+
proc_macro_unsafe::unsafe_block!(token);
250+
}
251+
244252
// Invalid comments
245253

246254
fn no_comment() {

tests/ui/undocumented_unsafe_blocks.stderr

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
error: unsafe block missing a safety comment
2-
--> $DIR/undocumented_unsafe_blocks.rs:247:5
2+
--> $DIR/undocumented_unsafe_blocks.rs:255:5
33
|
44
LL | unsafe {}
55
| ^^^^^^^^^
@@ -8,95 +8,95 @@ LL | unsafe {}
88
= help: consider adding a safety comment on the preceding line
99

1010
error: unsafe block missing a safety comment
11-
--> $DIR/undocumented_unsafe_blocks.rs:251:14
11+
--> $DIR/undocumented_unsafe_blocks.rs:259:14
1212
|
1313
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
1414
| ^^^^^^^^^^^^^
1515
|
1616
= help: consider adding a safety comment on the preceding line
1717

1818
error: unsafe block missing a safety comment
19-
--> $DIR/undocumented_unsafe_blocks.rs:251:29
19+
--> $DIR/undocumented_unsafe_blocks.rs:259:29
2020
|
2121
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
2222
| ^^^^^^^^^^^^^
2323
|
2424
= help: consider adding a safety comment on the preceding line
2525

2626
error: unsafe block missing a safety comment
27-
--> $DIR/undocumented_unsafe_blocks.rs:251:48
27+
--> $DIR/undocumented_unsafe_blocks.rs:259:48
2828
|
2929
LL | let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
3030
| ^^^^^^^^^^^^^
3131
|
3232
= help: consider adding a safety comment on the preceding line
3333

3434
error: unsafe block missing a safety comment
35-
--> $DIR/undocumented_unsafe_blocks.rs:255:18
35+
--> $DIR/undocumented_unsafe_blocks.rs:263:18
3636
|
3737
LL | let _ = (42, unsafe {}, "test", unsafe {});
3838
| ^^^^^^^^^
3939
|
4040
= help: consider adding a safety comment on the preceding line
4141

4242
error: unsafe block missing a safety comment
43-
--> $DIR/undocumented_unsafe_blocks.rs:255:37
43+
--> $DIR/undocumented_unsafe_blocks.rs:263:37
4444
|
4545
LL | let _ = (42, unsafe {}, "test", unsafe {});
4646
| ^^^^^^^^^
4747
|
4848
= help: consider adding a safety comment on the preceding line
4949

5050
error: unsafe block missing a safety comment
51-
--> $DIR/undocumented_unsafe_blocks.rs:259:14
51+
--> $DIR/undocumented_unsafe_blocks.rs:267:14
5252
|
5353
LL | let _ = *unsafe { &42 };
5454
| ^^^^^^^^^^^^^^
5555
|
5656
= help: consider adding a safety comment on the preceding line
5757

5858
error: unsafe block missing a safety comment
59-
--> $DIR/undocumented_unsafe_blocks.rs:264:19
59+
--> $DIR/undocumented_unsafe_blocks.rs:272:19
6060
|
6161
LL | let _ = match unsafe {} {
6262
| ^^^^^^^^^
6363
|
6464
= help: consider adding a safety comment on the preceding line
6565

6666
error: unsafe block missing a safety comment
67-
--> $DIR/undocumented_unsafe_blocks.rs:270:14
67+
--> $DIR/undocumented_unsafe_blocks.rs:278:14
6868
|
6969
LL | let _ = &unsafe {};
7070
| ^^^^^^^^^
7171
|
7272
= help: consider adding a safety comment on the preceding line
7373

7474
error: unsafe block missing a safety comment
75-
--> $DIR/undocumented_unsafe_blocks.rs:274:14
75+
--> $DIR/undocumented_unsafe_blocks.rs:282:14
7676
|
7777
LL | let _ = [unsafe {}; 5];
7878
| ^^^^^^^^^
7979
|
8080
= help: consider adding a safety comment on the preceding line
8181

8282
error: unsafe block missing a safety comment
83-
--> $DIR/undocumented_unsafe_blocks.rs:278:13
83+
--> $DIR/undocumented_unsafe_blocks.rs:286:13
8484
|
8585
LL | let _ = unsafe {};
8686
| ^^^^^^^^^
8787
|
8888
= help: consider adding a safety comment on the preceding line
8989

9090
error: unsafe block missing a safety comment
91-
--> $DIR/undocumented_unsafe_blocks.rs:288:8
91+
--> $DIR/undocumented_unsafe_blocks.rs:296:8
9292
|
9393
LL | t!(unsafe {});
9494
| ^^^^^^^^^
9595
|
9696
= help: consider adding a safety comment on the preceding line
9797

9898
error: unsafe block missing a safety comment
99-
--> $DIR/undocumented_unsafe_blocks.rs:294:13
99+
--> $DIR/undocumented_unsafe_blocks.rs:302:13
100100
|
101101
LL | unsafe {}
102102
| ^^^^^^^^^
@@ -108,31 +108,31 @@ LL | t!();
108108
= note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
109109

110110
error: unsafe block missing a safety comment
111-
--> $DIR/undocumented_unsafe_blocks.rs:302:5
111+
--> $DIR/undocumented_unsafe_blocks.rs:310:5
112112
|
113113
LL | unsafe {} // SAFETY:
114114
| ^^^^^^^^^
115115
|
116116
= help: consider adding a safety comment on the preceding line
117117

118118
error: unsafe block missing a safety comment
119-
--> $DIR/undocumented_unsafe_blocks.rs:306:5
119+
--> $DIR/undocumented_unsafe_blocks.rs:314:5
120120
|
121121
LL | unsafe {
122122
| ^^^^^^^^
123123
|
124124
= help: consider adding a safety comment on the preceding line
125125

126126
error: unsafe block missing a safety comment
127-
--> $DIR/undocumented_unsafe_blocks.rs:316:5
127+
--> $DIR/undocumented_unsafe_blocks.rs:324:5
128128
|
129129
LL | unsafe {};
130130
| ^^^^^^^^^
131131
|
132132
= help: consider adding a safety comment on the preceding line
133133

134134
error: unsafe block missing a safety comment
135-
--> $DIR/undocumented_unsafe_blocks.rs:320:20
135+
--> $DIR/undocumented_unsafe_blocks.rs:328:20
136136
|
137137
LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
138138
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

0 commit comments

Comments
 (0)