mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-24 05:33:27 +00:00
Adding configuration to allow safety comment above stmt containing unsafe block
This commit is contained in:
parent
965f4a8492
commit
520228b377
9 changed files with 93 additions and 7 deletions
|
@ -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)
|
* [`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 `usafe` block
|
||||||
|
|
||||||
|
**Default Value:** `false` (`bool`)
|
||||||
|
|
||||||
|
---
|
||||||
|
**Affected lints:**
|
||||||
|
* [`undocumented_unsafe_blocks`](https://rust-lang.github.io/rust-clippy/master/index.html#undocumented_unsafe_blocks)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -929,7 +929,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
||||||
enable_raw_pointer_heuristic_for_send,
|
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;
|
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(move |_| Box::new(format_args::FormatArgs::new(msrv(), allow_mixed_uninlined)));
|
||||||
store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray));
|
store.register_late_pass(|_| Box::new(trailing_empty_array::TrailingEmptyArray));
|
||||||
|
|
|
@ -11,7 +11,7 @@ use rustc_hir::{Block, BlockCheckMode, ItemKind, Node, UnsafeSource};
|
||||||
use rustc_lexer::{tokenize, TokenKind};
|
use rustc_lexer::{tokenize, TokenKind};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
||||||
use rustc_middle::lint::in_external_macro;
|
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};
|
use rustc_span::{BytePos, Pos, Span, SyntaxContext};
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
|
@ -92,7 +92,20 @@ declare_clippy_lint! {
|
||||||
"annotating safe code with a safety comment"
|
"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 {
|
impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
|
||||||
fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
|
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_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, block.hir_id)
|
||||||
&& !is_unsafe_from_proc_macro(cx, block.span)
|
&& !is_unsafe_from_proc_macro(cx, block.span)
|
||||||
&& !block_has_safety_comment(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 source_map = cx.tcx.sess.source_map();
|
||||||
let span = if source_map.is_multiline(block.span) {
|
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}
|
// Checks if any parent {expression, statement, block, local, const, static}
|
||||||
// has a safety comment
|
// 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) {
|
if let Some(node) = get_parent_node(cx.tcx, id) {
|
||||||
return match node {
|
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 {
|
Node::Stmt(hir::Stmt {
|
||||||
kind:
|
kind:
|
||||||
hir::StmtKind::Local(hir::Local { span, .. })
|
hir::StmtKind::Local(hir::Local { span, .. })
|
||||||
|
|
|
@ -538,6 +538,10 @@ define_Conf! {
|
||||||
///
|
///
|
||||||
/// Minimum chars an ident can have, anything below or equal to this will be linted.
|
/// Minimum chars an ident can have, anything below or equal to this will be linted.
|
||||||
(min_ident_chars_threshold: u64 = 1),
|
(min_ident_chars_threshold: u64 = 1),
|
||||||
|
/// Lint: UNDOCUMENTED_UNSAFE_BLOCKS.
|
||||||
|
///
|
||||||
|
/// Whether to accept a safety comment to be placed above the statement containing the `usafe` block
|
||||||
|
(accept_comment_above_statement: bool = false),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Search for the configuration file.
|
/// Search for the configuration file.
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
error: error reading Clippy's configuration file: unknown field `foobar`, expected one of
|
error: error reading Clippy's configuration file: unknown field `foobar`, expected one of
|
||||||
|
accept-comment-above-statement
|
||||||
allow-dbg-in-tests
|
allow-dbg-in-tests
|
||||||
allow-expect-in-tests
|
allow-expect-in-tests
|
||||||
allow-mixed-uninlined-format-args
|
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
|
error: error reading Clippy's configuration file: unknown field `barfoo`, expected one of
|
||||||
|
accept-comment-above-statement
|
||||||
allow-dbg-in-tests
|
allow-dbg-in-tests
|
||||||
allow-expect-in-tests
|
allow-expect-in-tests
|
||||||
allow-mixed-uninlined-format-args
|
allow-mixed-uninlined-format-args
|
||||||
|
|
1
tests/ui-toml/undocumented_unsafe_blocks/clippy.toml
Normal file
1
tests/ui-toml/undocumented_unsafe_blocks/clippy.toml
Normal file
|
@ -0,0 +1 @@
|
||||||
|
accept-comment-above-statement = true
|
|
@ -0,0 +1,12 @@
|
||||||
|
#![deny(clippy::undocumented_unsafe_blocks)]
|
||||||
|
#![allow(clippy::missing_safety_doc)]
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
// 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() };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 {
|
||||||
|
1
|
||||||
|
}
|
|
@ -509,4 +509,14 @@ fn issue_9142() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 {
|
||||||
|
1
|
||||||
|
}
|
||||||
|
|
||||||
|
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() };
|
||||||
|
}
|
||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
|
@ -318,5 +318,13 @@ LL | let bar = unsafe {};
|
||||||
|
|
|
|
||||||
= help: consider adding a safety comment on the preceding line
|
= 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:519: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: aborting due to 37 previous errors
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue