Skip to content

Commit 5d0ca74

Browse files
committed
Resolved conflicts
1 parent 1594e98 commit 5d0ca74

File tree

3 files changed

+212
-3
lines changed

3 files changed

+212
-3
lines changed

clippy_lints/src/undocumented_unsafe_blocks.rs

Lines changed: 63 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@ use clippy_utils::diagnostics::span_lint_and_help;
22
use clippy_utils::is_lint_allowed;
33
use clippy_utils::source::walk_span_to_context;
44
use rustc_data_structures::sync::Lrc;
5+
use rustc_hir as hir;
56
use rustc_hir::{Block, BlockCheckMode, UnsafeSource};
67
use rustc_lexer::{tokenize, TokenKind};
78
use rustc_lint::{LateContext, LateLintPass, LintContext};
89
use rustc_middle::lint::in_external_macro;
910
use rustc_session::{declare_lint_pass, declare_tool_lint};
10-
use rustc_span::{BytePos, Pos, SyntaxContext};
11+
use rustc_span::{BytePos, Pos, Span, SyntaxContext};
12+
use std::rc::Rc;
1113

1214
declare_clippy_lint! {
1315
/// ### What it does
@@ -86,6 +88,66 @@ impl LateLintPass<'_> for UndocumentedUnsafeBlocks {
8688
);
8789
}
8890
}
91+
92+
fn check_mod(&mut self, cx: &LateContext<'_>, module: &'_ hir::Mod<'_>, mod_span: Span, hir_id: hir::HirId) {
93+
let source_map = cx.sess().source_map();
94+
let mut item_and_spans: Vec<(&hir::Item<'_>, Span)> = Vec::new(); // (start, end, item)
95+
96+
// Collect all items and their spans
97+
for item_id in module.item_ids {
98+
let item = cx.tcx.hir().item(*item_id);
99+
item_and_spans.push((item, item.span));
100+
}
101+
// Sort items by start position
102+
item_and_spans.sort_by_key(|e| e.1.lo());
103+
104+
for (idx, (item, item_span)) in item_and_spans.iter().enumerate() {
105+
if let hir::ItemKind::Impl(imple) = &item.kind
106+
&& imple.unsafety == hir::Unsafety::Unsafe
107+
&& !item_span.from_expansion()
108+
&& !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, hir_id)
109+
{
110+
// Checks if the lines immediately preceding the impl contain a safety comment.
111+
let impl_has_safety_comment = {
112+
let span_before_impl = if idx == 0 {
113+
// mod A { /* comment */ unsafe impl T {} }
114+
// ^--------------------^
115+
todo!();
116+
//mod_span.until(module.spans)
117+
} else {
118+
// unsafe impl S {} /* comment */ unsafe impl T {}
119+
// ^-------------^
120+
item_and_spans[idx - 1].1.between(*item_span)
121+
};
122+
123+
if let Ok(start) = source_map.lookup_line(span_before_impl.lo())
124+
&& let Ok(end) = source_map.lookup_line(span_before_impl.hi())
125+
&& let Some(src) = start.sf.src.as_deref()
126+
{
127+
start.line < end.line && text_has_safety_comment(
128+
src,
129+
&start.sf.lines[start.line + 1 ..= end.line],
130+
start.sf.start_pos.to_usize()
131+
)
132+
} else {
133+
// Problem getting source text. Pretend a comment was found.
134+
true
135+
}
136+
};
137+
138+
if !impl_has_safety_comment {
139+
span_lint_and_help(
140+
cx,
141+
UNDOCUMENTED_UNSAFE_BLOCKS,
142+
*item_span,
143+
"unsafe impl missing a safety comment",
144+
None,
145+
"consider adding a safety comment on the preceding line",
146+
);
147+
}
148+
}
149+
}
150+
}
89151
}
90152

91153
fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, block: &Block<'_>) -> bool {

tests/ui/undocumented_unsafe_blocks.rs

Lines changed: 100 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// aux-build:proc_macro_unsafe.rs
22

33
#![warn(clippy::undocumented_unsafe_blocks)]
4-
#![allow(clippy::let_unit_value)]
4+
#![allow(clippy::let_unit_value, clippy::missing_safety_doc)]
55

66
extern crate proc_macro_unsafe;
77

@@ -334,4 +334,103 @@ pub fn print_binary_tree() {
334334
println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
335335
}
336336

337+
mod unsafe_impl_smoke_test {
338+
unsafe trait A {}
339+
340+
// error: no safety comment
341+
unsafe impl A for () {}
342+
343+
// Safety: ok
344+
unsafe impl A for (i32) {}
345+
346+
mod sub_mod {
347+
// error: also works for the first item
348+
unsafe impl B for (u32) {}
349+
unsafe trait B {}
350+
}
351+
352+
#[rustfmt::skip]
353+
mod sub_mod2 {
354+
//
355+
// SAFETY: ok
356+
//
357+
358+
unsafe impl B for (u32) {}
359+
unsafe trait B {}
360+
}
361+
}
362+
363+
mod unsafe_impl_from_macro {
364+
unsafe trait T {}
365+
366+
macro_rules! unsafe_impl {
367+
($t:ty) => {
368+
unsafe impl T for $t {}
369+
};
370+
}
371+
// ok: from macro expanision
372+
unsafe_impl!(());
373+
// ok: from macro expansion
374+
unsafe_impl!(i32);
375+
}
376+
377+
#[rustfmt::skip]
378+
mod unsafe_impl_valid_comment {
379+
unsafe trait SaFety {}
380+
// SaFety:
381+
unsafe impl SaFety for () {}
382+
383+
unsafe trait MultiLineComment {}
384+
// The following impl is safe
385+
// ...
386+
// Safety: reason
387+
unsafe impl MultiLineComment for () {}
388+
389+
unsafe trait NoAscii {}
390+
// 安全 SAFETY: 以下のコードは安全です
391+
unsafe impl NoAscii for () {}
392+
393+
unsafe trait InlineAndPrecedingComment {}
394+
// SAFETY:
395+
/* comment */ unsafe impl InlineAndPrecedingComment for () {}
396+
397+
unsafe trait BuriedSafety {}
398+
// Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
399+
// incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
400+
// ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
401+
// reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
402+
// occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
403+
// laborum. Safety:
404+
// Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi
405+
// morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio
406+
// ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl
407+
// condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.
408+
unsafe impl BuriedSafety for () {}
409+
410+
unsafe trait MultiLineBlockComment {}
411+
/* This is a description
412+
* Safety: */
413+
unsafe impl MultiLineBlockComment for () {}
414+
}
415+
416+
#[rustfmt::skip]
417+
mod unsafe_impl_invalid_comment {
418+
unsafe trait NoComment {}
419+
420+
unsafe impl NoComment for () {}
421+
422+
unsafe trait InlineComment {}
423+
424+
/* SAFETY: */ unsafe impl InlineComment for () {}
425+
426+
unsafe trait TrailingComment {}
427+
428+
unsafe impl TrailingComment for () {} // SAFETY:
429+
430+
unsafe trait Interference {}
431+
// SAFETY:
432+
const BIG_NUMBER: i32 = 1000000;
433+
unsafe impl Interference for () {}
434+
}
435+
337436
fn main() {}

tests/ui/undocumented_unsafe_blocks.stderr

Lines changed: 49 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,5 +147,53 @@ LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
147147
|
148148
= help: consider adding a safety comment on the preceding line
149149

150-
error: aborting due to 18 previous errors
150+
error: unsafe impl missing a safety comment
151+
--> $DIR/undocumented_unsafe_blocks.rs:341:5
152+
|
153+
LL | unsafe impl A for () {}
154+
| ^^^^^^^^^^^^^^^^^^^^^^^
155+
|
156+
= help: consider adding a safety comment on the preceding line
157+
158+
error: unsafe impl missing a safety comment
159+
--> $DIR/undocumented_unsafe_blocks.rs:348:9
160+
|
161+
LL | unsafe impl B for (u32) {}
162+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
163+
|
164+
= help: consider adding a safety comment on the preceding line
165+
166+
error: unsafe impl missing a safety comment
167+
--> $DIR/undocumented_unsafe_blocks.rs:420:5
168+
|
169+
LL | unsafe impl NoComment for () {}
170+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
171+
|
172+
= help: consider adding a safety comment on the preceding line
173+
174+
error: unsafe impl missing a safety comment
175+
--> $DIR/undocumented_unsafe_blocks.rs:424:19
176+
|
177+
LL | /* SAFETY: */ unsafe impl InlineComment for () {}
178+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
179+
|
180+
= help: consider adding a safety comment on the preceding line
181+
182+
error: unsafe impl missing a safety comment
183+
--> $DIR/undocumented_unsafe_blocks.rs:428:5
184+
|
185+
LL | unsafe impl TrailingComment for () {} // SAFETY:
186+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
187+
|
188+
= help: consider adding a safety comment on the preceding line
189+
190+
error: unsafe impl missing a safety comment
191+
--> $DIR/undocumented_unsafe_blocks.rs:433:5
192+
|
193+
LL | unsafe impl Interference for () {}
194+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
195+
|
196+
= help: consider adding a safety comment on the preceding line
197+
198+
error: aborting due to 24 previous errors
151199

0 commit comments

Comments
 (0)