diff --git a/CHANGELOG.md b/CHANGELOG.md index 269be545b0a..3eaa0d199fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5383,4 +5383,5 @@ Released 2018-09-13 [`allow-private-module-inception`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-private-module-inception [`allowed-idents-below-min-chars`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-idents-below-min-chars [`min-ident-chars-threshold`]: https://doc.rust-lang.org/clippy/lint_configuration.html#min-ident-chars-threshold +[`accept-comment-above-statement`]: https://doc.rust-lang.org/clippy/lint_configuration.html#accept-comment-above-statement diff --git a/book/src/lint_configuration.md b/book/src/lint_configuration.md index 085dff8e63b..78a5f9da461 100644 --- a/book/src/lint_configuration.md +++ b/book/src/lint_configuration.md @@ -695,3 +695,13 @@ Minimum chars an ident can have, anything below or equal to this will be linted. * [`min_ident_chars`](https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars) +## `accept-comment-above-statement` +Whether to accept a safety comment to be placed above the statement containing the `unsafe` block + +**Default Value:** `false` (`bool`) + +--- +**Affected lints:** +* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks) + + diff --git a/clippy_lints/src/lib.rs b/clippy_lints/src/lib.rs index f0a873b91eb..6ea329a9542 100644 --- a/clippy_lints/src/lib.rs +++ b/clippy_lints/src/lib.rs @@ -929,7 +929,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf: enable_raw_pointer_heuristic_for_send, )) }); - store.register_late_pass(move |_| Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks)); + let accept_comment_above_statement = conf.accept_comment_above_statement; + store.register_late_pass(move |_| { + Box::new(undocumented_unsafe_blocks::UndocumentedUnsafeBlocks::new( + accept_comment_above_statement, + )) + }); let allow_mixed_uninlined = conf.allow_mixed_uninlined_format_args; store.register_late_pass(move |_| Box::new(format_args::FormatArgs::new(msrv(), allow_mixed_uninlined))); store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray)); diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index 2920684ade3..1676c767a34 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -11,7 +11,7 @@ use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource}; use rustc_lexer::{tokenize, TokenKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; -use rustc_session::{declare_lint_pass, declare_tool_lint}; +use rustc_session::{declare_tool_lint, impl_lint_pass}; use rustc_span::{BytePos, Pos, Span, SyntaxContext}; declare_clippy_lint! { @@ -92,7 +92,20 @@ declare_clippy_lint! { "annotating safe code with a safety comment" } -declare_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS, UNNECESSARY_SAFETY_COMMENT]); +#[derive(Copy, Clone)] +pub struct UndocumentedUnsafeBlocks { + accept_comment_above_statement: bool, +} + +impl UndocumentedUnsafeBlocks { + pub fn new(accept_comment_above_statement: bool) -> Self { + Self { + accept_comment_above_statement, + } + } +} + +impl_lint_pass!(UndocumentedUnsafeBlocks => [UNDOCUMENTED_UNSAFE_BLOCKS, UNNECESSARY_SAFETY_COMMENT]); impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) { @@ -101,7 +114,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks { && !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id) && !is_unsafe_from_proc_macro(cx, block.span) && !block_has_safety_comment(cx, block.span) - && !block_parents_have_safety_comment(cx, block.hir_id) + && !block_parents_have_safety_comment(self.accept_comment_above_statement, cx, block.hir_id) { let source_map = cx.tcx.sess.source_map(); let span = if source_map.is_multiline(block.span) { @@ -313,10 +326,31 @@ fn is_unsafe_from_proc_macro(cx: &LateContext<'_>, span: Span) -> bool { // Checks if any parent {expression, statement, block, local, const, static} // has a safety comment -fn block_parents_have_safety_comment(cx: &LateContext<'_>, id: hir::HirId) -> bool { +fn block_parents_have_safety_comment( + accept_comment_above_statement: bool, + cx: &LateContext<'_>, + id: hir::HirId, +) -> bool { if let Some(node) = get_parent_node(cx.tcx, id) { return match node { - Node::Expr(expr) => !is_branchy(expr) && span_in_body_has_safety_comment(cx, expr.span), + Node::Expr(expr) => { + if let Some( + Node::Local(hir::Local { span, .. }) + | Node::Item(hir::Item { + kind: hir::ItemKind::Const(..) | ItemKind::Static(..), + span, + .. + }), + ) = get_parent_node(cx.tcx, expr.hir_id) + { + // if unsafe block is part of a let/const/static statement, + // and accept_comment_above_statement is set to true + // we accept the safety comment in the line the precedes this statement. + accept_comment_above_statement && span_in_body_has_safety_comment(cx, *span) + } else { + !is_branchy(expr) && span_in_body_has_safety_comment(cx, expr.span) + } + }, Node::Stmt(hir::Stmt { kind: hir::StmtKind::Local(hir::Local { span, .. }) @@ -546,7 +580,14 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option { for (_, node) in map.parent_iter(body.hir_id) { match node { Node::Expr(e) => span = e.span, - Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::Local(_) => (), + Node::Block(_) + | Node::Arm(_) + | Node::Stmt(_) + | Node::Local(_) + | Node::Item(hir::Item { + kind: hir::ItemKind::Const(..) | ItemKind::Static(..), + .. + }) => (), _ => break, } } diff --git a/clippy_lints/src/utils/conf.rs b/clippy_lints/src/utils/conf.rs index f6c7c1fa065..e8c8d478ffc 100644 --- a/clippy_lints/src/utils/conf.rs +++ b/clippy_lints/src/utils/conf.rs @@ -538,6 +538,10 @@ define_Conf! { /// /// Minimum chars an ident can have, anything below or equal to this will be linted. (min_ident_chars_threshold: u64 = 1), + /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS. + /// + /// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block + (accept_comment_above_statement: bool = false), } /// Search for the configuration file. diff --git a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr index d8ce0e2f55d..db2071ecaaf 100644 --- a/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr +++ b/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr @@ -1,4 +1,5 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expected one of + accept-comment-above-statement allow-dbg-in-tests allow-expect-in-tests allow-mixed-uninlined-format-args @@ -65,6 +66,7 @@ LL | foobar = 42 | ^^^^^^ error: error reading Clippy's configuration file: unknown field `barfoo`, expected one of + accept-comment-above-statement allow-dbg-in-tests allow-expect-in-tests allow-mixed-uninlined-format-args diff --git a/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs b/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs new file mode 100644 index 00000000000..c2326678d0d --- /dev/null +++ b/tests/ui-toml/undocumented_unsafe_blocks/auxiliary/proc_macro_unsafe.rs @@ -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) + }]) +} diff --git a/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml b/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml new file mode 100644 index 00000000000..1c2e7aeaff9 --- /dev/null +++ b/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml @@ -0,0 +1 @@ +accept-comment-above-statement = true diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs new file mode 100644 index 00000000000..533f90483e5 --- /dev/null +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs @@ -0,0 +1,534 @@ +//@aux-build:proc_macro_unsafe.rs + +#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)] +#![allow(clippy::let_unit_value, clippy::missing_safety_doc)] + +extern crate proc_macro_unsafe; + +// Valid comments + +fn nested_local() { + let _ = { + let _ = { + // SAFETY: + let _ = unsafe {}; + }; + }; +} + +fn deep_nest() { + let _ = { + let _ = { + // SAFETY: + let _ = unsafe {}; + + // Safety: + unsafe {}; + + let _ = { + let _ = { + let _ = { + let _ = { + let _ = { + // Safety: + let _ = unsafe {}; + + // SAFETY: + unsafe {}; + }; + }; + }; + + // Safety: + unsafe {}; + }; + }; + }; + + // Safety: + unsafe {}; + }; + + // SAFETY: + unsafe {}; +} + +fn local_tuple_expression() { + // Safety: + let _ = (42, unsafe {}); +} + +fn line_comment() { + // Safety: + unsafe {} +} + +fn line_comment_newlines() { + // SAFETY: + + unsafe {} +} + +fn line_comment_empty() { + // Safety: + // + // + // + unsafe {} +} + +fn line_comment_with_extras() { + // This is a description + // Safety: + unsafe {} +} + +fn block_comment() { + /* Safety: */ + unsafe {} +} + +fn block_comment_newlines() { + /* SAFETY: */ + + unsafe {} +} + +fn block_comment_with_extras() { + /* This is a description + * SAFETY: + */ + unsafe {} +} + +fn block_comment_terminator_same_line() { + /* This is a description + * Safety: */ + unsafe {} +} + +fn buried_safety() { + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + // laborum. Safety: + // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi + // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio + // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl + // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. + unsafe {} +} + +fn safety_with_prepended_text() { + // This is a test. safety: + unsafe {} +} + +fn local_line_comment() { + // Safety: + let _ = unsafe {}; +} + +fn local_block_comment() { + /* SAFETY: */ + let _ = unsafe {}; +} + +fn comment_array() { + // Safety: + let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; +} + +fn comment_tuple() { + // sAFETY: + let _ = (42, unsafe {}, "test", unsafe {}); +} + +fn comment_unary() { + // SAFETY: + let _ = *unsafe { &42 }; +} + +#[allow(clippy::match_single_binding)] +fn comment_match() { + // SAFETY: + let _ = match unsafe {} { + _ => {}, + }; +} + +fn comment_addr_of() { + // Safety: + let _ = &unsafe {}; +} + +fn comment_repeat() { + // Safety: + let _ = [unsafe {}; 5]; +} + +fn comment_macro_call() { + macro_rules! t { + ($b:expr) => { + $b + }; + } + + t!( + // SAFETY: + unsafe {} + ); +} + +fn comment_macro_def() { + macro_rules! t { + () => { + // Safety: + unsafe {} + }; + } + + t!(); +} + +fn non_ascii_comment() { + // ॐ᧻໒ SaFeTy: ௵∰ + unsafe {}; +} + +fn local_commented_block() { + let _ = + // safety: + unsafe {}; +} + +fn local_nest() { + // safety: + let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})]; +} + +fn in_fn_call(x: *const u32) { + fn f(x: u32) {} + + // Safety: reason + f(unsafe { *x }); +} + +fn multi_in_fn_call(x: *const u32) { + fn f(x: u32, y: u32) {} + + // Safety: reason + f(unsafe { *x }, unsafe { *x }); +} + +fn in_multiline_fn_call(x: *const u32) { + fn f(x: u32, y: u32) {} + + f( + // Safety: reason + unsafe { *x }, + 0, + ); +} + +fn in_macro_call(x: *const u32) { + // Safety: reason + println!("{}", unsafe { *x }); +} + +fn in_multiline_macro_call(x: *const u32) { + println!( + "{}", + // Safety: reason + unsafe { *x }, + ); +} + +fn from_proc_macro() { + proc_macro_unsafe::unsafe_block!(token); +} + +fn in_closure(x: *const u32) { + // Safety: reason + let _ = || unsafe { *x }; +} + +// Invalid comments + +#[rustfmt::skip] +fn inline_block_comment() { + /* Safety: */ unsafe {} +} + +fn no_comment() { + unsafe {} +} + +fn no_comment_array() { + let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }]; +} + +fn no_comment_tuple() { + let _ = (42, unsafe {}, "test", unsafe {}); +} + +fn no_comment_unary() { + let _ = *unsafe { &42 }; +} + +#[allow(clippy::match_single_binding)] +fn no_comment_match() { + let _ = match unsafe {} { + _ => {}, + }; +} + +fn no_comment_addr_of() { + let _ = &unsafe {}; +} + +fn no_comment_repeat() { + let _ = [unsafe {}; 5]; +} + +fn local_no_comment() { + let _ = unsafe {}; +} + +fn no_comment_macro_call() { + macro_rules! t { + ($b:expr) => { + $b + }; + } + + t!(unsafe {}); +} + +fn no_comment_macro_def() { + macro_rules! t { + () => { + unsafe {} + }; + } + + t!(); +} + +fn trailing_comment() { + unsafe {} // SAFETY: +} + +fn internal_comment() { + unsafe { + // SAFETY: + } +} + +fn interference() { + // SAFETY + + let _ = 42; + + unsafe {}; +} + +pub fn print_binary_tree() { + println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); +} + +mod unsafe_impl_smoke_test { + unsafe trait A {} + + // error: no safety comment + unsafe impl A for () {} + + // Safety: ok + unsafe impl A for (i32) {} + + mod sub_mod { + // error: + unsafe impl B for (u32) {} + unsafe trait B {} + } + + #[rustfmt::skip] + mod sub_mod2 { + // + // SAFETY: ok + // + + unsafe impl B for (u32) {} + unsafe trait B {} + } +} + +mod unsafe_impl_from_macro { + unsafe trait T {} + + // error + macro_rules! no_safety_comment { + ($t:ty) => { + unsafe impl T for $t {} + }; + } + + // ok + no_safety_comment!(()); + + // ok + macro_rules! with_safety_comment { + ($t:ty) => { + // SAFETY: + unsafe impl T for $t {} + }; + } + + // ok + with_safety_comment!((i32)); +} + +mod unsafe_impl_macro_and_not_macro { + unsafe trait T {} + + // error + macro_rules! no_safety_comment { + ($t:ty) => { + unsafe impl T for $t {} + }; + } + + // ok + no_safety_comment!(()); + + // error + unsafe impl T for (i32) {} + + // ok + no_safety_comment!(u32); + + // error + unsafe impl T for (bool) {} +} + +#[rustfmt::skip] +mod unsafe_impl_valid_comment { + unsafe trait SaFety {} + // SaFety: + unsafe impl SaFety for () {} + + unsafe trait MultiLineComment {} + // The following impl is safe + // ... + // Safety: reason + unsafe impl MultiLineComment for () {} + + unsafe trait NoAscii {} + // 安全 SAFETY: 以下のコードは安全です + unsafe impl NoAscii for () {} + + unsafe trait InlineAndPrecedingComment {} + // SAFETY: + /* comment */ unsafe impl InlineAndPrecedingComment for () {} + + unsafe trait BuriedSafety {} + // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor + // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation + // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in + // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint + // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est + // laborum. Safety: + // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi + // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio + // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl + // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus. + unsafe impl BuriedSafety for () {} + + unsafe trait MultiLineBlockComment {} + /* This is a description + * Safety: */ + unsafe impl MultiLineBlockComment for () {} +} + +#[rustfmt::skip] +mod unsafe_impl_invalid_comment { + unsafe trait NoComment {} + + unsafe impl NoComment for () {} + + unsafe trait InlineComment {} + + /* SAFETY: */ unsafe impl InlineComment for () {} + + unsafe trait TrailingComment {} + + unsafe impl TrailingComment for () {} // SAFETY: + + unsafe trait Interference {} + // SAFETY: + const BIG_NUMBER: i32 = 1000000; + unsafe impl Interference for () {} +} + +unsafe trait ImplInFn {} + +fn impl_in_fn() { + // error + unsafe impl ImplInFn for () {} + + // SAFETY: ok + unsafe impl ImplInFn for (i32) {} +} + +unsafe trait CrateRoot {} + +// error +unsafe impl CrateRoot for () {} + +// SAFETY: ok +unsafe impl CrateRoot for (i32) {} + +fn issue_9142() { + // SAFETY: ok + let _ = + // we need this comment to avoid rustfmt putting + // it all on one line + unsafe {}; + + // SAFETY: this is more than one level away, so it should warn + let _ = { + if unsafe { true } { + todo!(); + } else { + let bar = unsafe {}; + todo!(); + bar + } + }; +} + +pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 { + 1 +} + +pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 { + 2 +} + +fn issue_10832() { + // Safety: A safety comment + let _some_variable_with_a_very_long_name_to_break_the_line = + unsafe { a_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Another safety comment + const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Yet another safety comment + static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; +} + +fn main() {} diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr new file mode 100644 index 00000000000..ac987a9e995 --- /dev/null +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr @@ -0,0 +1,314 @@ +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:262:19 + | +LL | /* Safety: */ unsafe {} + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings` + +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:266: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:270: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:270: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:270: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:274: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:274: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:278: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:283: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:289: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:293: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:297: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:307: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:313:13 + | +LL | unsafe {} + | ^^^^^^^^^ +... +LL | t!(); + | ---- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = 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:321: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:325: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:335: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:339:20 + | +LL | println!("{}", unsafe { String::from_utf8_unchecked(vec![]) }); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:346:5 + | +LL | unsafe impl A for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:353:9 + | +LL | unsafe impl B for (u32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:374:13 + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(()); + | ---------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:399:13 + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(()); + | ---------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:407:5 + | +LL | unsafe impl T for (i32) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:399:13 + | +LL | unsafe impl T for $t {} + | ^^^^^^^^^^^^^^^^^^^^^^^ +... +LL | no_safety_comment!(u32); + | ----------------------- in this macro invocation + | + = help: consider adding a safety comment on the preceding line + = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:413:5 + | +LL | unsafe impl T for (bool) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:459:5 + | +LL | unsafe impl NoComment for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:463:19 + | +LL | /* SAFETY: */ unsafe impl InlineComment for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:467:5 + | +LL | unsafe impl TrailingComment for () {} // SAFETY: + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: constant item has unnecessary safety comment + --> $DIR/undocumented_unsafe_blocks.rs:471:5 + | +LL | const BIG_NUMBER: i32 = 1000000; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +help: consider removing the safety comment + --> $DIR/undocumented_unsafe_blocks.rs:470:5 + | +LL | // SAFETY: + | ^^^^^^^^^^ + = note: `-D clippy::unnecessary-safety-comment` implied by `-D warnings` + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:472:5 + | +LL | unsafe impl Interference for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:479:5 + | +LL | unsafe impl ImplInFn for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe impl missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:488:1 + | +LL | unsafe impl CrateRoot for () {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: statement has unnecessary safety comment + --> $DIR/undocumented_unsafe_blocks.rs:501:5 + | +LL | / let _ = { +LL | | if unsafe { true } { +LL | | todo!(); +LL | | } else { +... | +LL | | } +LL | | }; + | |______^ + | +help: consider removing the safety comment + --> $DIR/undocumented_unsafe_blocks.rs:500:5 + | +LL | // SAFETY: this is more than one level away, so it should warn + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:502:12 + | +LL | if unsafe { true } { + | ^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:505:23 + | +LL | let bar = unsafe {}; + | ^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: aborting due to 35 previous errors + diff --git a/tests/ui/undocumented_unsafe_blocks.rs b/tests/ui/undocumented_unsafe_blocks.rs index 229d150851a..f4e7f1943ae 100644 --- a/tests/ui/undocumented_unsafe_blocks.rs +++ b/tests/ui/undocumented_unsafe_blocks.rs @@ -509,4 +509,26 @@ fn issue_9142() { }; } +pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 { + 1 +} + +pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 { + 2 +} + +fn issue_10832() { + // Safety: A safety comment. But it will warn anyways + let _some_variable_with_a_very_long_name_to_break_the_line = + unsafe { a_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Another safety comment. But it will warn anyways + const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + + // Safety: Yet another safety comment. But it will warn anyways + static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 = + unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; +} + fn main() {} diff --git a/tests/ui/undocumented_unsafe_blocks.stderr b/tests/ui/undocumented_unsafe_blocks.stderr index d1c1bb5ffea..ee1d3aa285a 100644 --- a/tests/ui/undocumented_unsafe_blocks.stderr +++ b/tests/ui/undocumented_unsafe_blocks.stderr @@ -318,5 +318,29 @@ LL | let bar = unsafe {}; | = help: consider adding a safety comment on the preceding line -error: aborting due to 36 previous errors +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:523:9 + | +LL | unsafe { a_function_with_a_very_long_name_to_break_the_line() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:527:9 + | +LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: unsafe block missing a safety comment + --> $DIR/undocumented_unsafe_blocks.rs:531:9 + | +LL | unsafe { a_const_function_with_a_very_long_name_to_break_the_line() }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: consider adding a safety comment on the preceding line + +error: aborting due to 39 previous errors