Skip to content

Commit

Permalink
Don't lint undocumented_unsafe_blocks on bad proc-macro spans.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jarcho committed Mar 15, 2022
1 parent 65f96e2 commit 30b3336
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 17 deletions.
12 changes: 12 additions & 0 deletions clippy_lints/src/undocumented_unsafe_blocks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
if block.rules == BlockCheckMode::UnsafeBlock(UnsafeSource::UserProvided)
&& !in_external_macro(cx.tcx.sess, block.span)
&& !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
&& !is_unsafe_from_proc_macro(cx, block)
&& !block_has_safety_comment(cx, block)
{
let source_map = cx.tcx.sess.source_map();
Expand All @@ -69,6 +70,17 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
}
}

fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
let source_map = cx.sess().source_map();
let file_pos = source_map.lookup_byte_offset(block.span.lo());
file_pos
.sf
.src
.as_deref()
.and_then(|src| src.get(file_pos.pos.to_usize()..))
.map_or(true, |src| !src.starts_with("unsafe"))
}

/// Checks if the lines immediately preceding the block contain a safety comment.
fn block_has_safety_comment(cx: &LateContext<'_>, block: &Block<'_>) -> bool {
// This intentionally ignores text before the start of a function so something like:
Expand Down
18 changes: 18 additions & 0 deletions tests/ui/auxiliary/proc_macro_unsafe.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// compile-flags: --emit=link
// no-prefer-dynamic

#![crate_type = "proc-macro"]

extern crate proc_macro;

use proc_macro::{Delimiter, Group, Ident, TokenStream, TokenTree};

#[proc_macro]
pub fn unsafe_block(input: TokenStream) -> TokenStream {
let span = input.into_iter().next().unwrap().span();
TokenStream::from_iter([TokenTree::Ident(Ident::new("unsafe", span)), {
let mut group = Group::new(Delimiter::Brace, TokenStream::new());
group.set_span(span);
TokenTree::Group(group)
}])
}
8 changes: 8 additions & 0 deletions tests/ui/undocumented_unsafe_blocks.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
// aux-build:proc_macro_unsafe.rs

#![warn(clippy::undocumented_unsafe_blocks)]

extern crate proc_macro_unsafe;

// Valid comments

fn nested_local() {
Expand Down Expand Up @@ -241,6 +245,10 @@ fn in_multiline_macro_call(x: *const u32) {
);
}

fn from_proc_macro() {
proc_macro_unsafe::unsafe_block!(token);
}

// Invalid comments

fn no_comment() {
Expand Down
34 changes: 17 additions & 17 deletions tests/ui/undocumented_unsafe_blocks.stderr
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
error: unsafe block missing a safety comment
--> $DIR/undocumented_unsafe_blocks.rs:247:5
--> $DIR/undocumented_unsafe_blocks.rs:255:5
|
LL | unsafe {}
| ^^^^^^^^^
Expand All @@ -8,95 +8,95 @@ LL | unsafe {}
= help: consider adding a safety comment on the preceding line

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

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

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

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

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

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

error: unsafe block missing a safety comment
--> $DIR/undocumented_unsafe_blocks.rs:264:19
--> $DIR/undocumented_unsafe_blocks.rs:272:19
|
LL | let _ = match unsafe {} {
| ^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line

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

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

error: unsafe block missing a safety comment
--> $DIR/undocumented_unsafe_blocks.rs:278:13
--> $DIR/undocumented_unsafe_blocks.rs:286:13
|
LL | let _ = unsafe {};
| ^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line

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

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

error: unsafe block missing a safety comment
--> $DIR/undocumented_unsafe_blocks.rs:302:5
--> $DIR/undocumented_unsafe_blocks.rs:310:5
|
LL | unsafe {} // SAFETY:
| ^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line

error: unsafe block missing a safety comment
--> $DIR/undocumented_unsafe_blocks.rs:306:5
--> $DIR/undocumented_unsafe_blocks.rs:314:5
|
LL | unsafe {
| ^^^^^^^^
|
= help: consider adding a safety comment on the preceding line

error: unsafe block missing a safety comment
--> $DIR/undocumented_unsafe_blocks.rs:316:5
--> $DIR/undocumented_unsafe_blocks.rs:324:5
|
LL | unsafe {};
| ^^^^^^^^^
|
= help: consider adding a safety comment on the preceding line

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

0 comments on commit 30b3336

Please sign in to comment.