diff options
| author | J-ZhengLi <lizheng135@huawei.com> | 2023-08-22 10:27:16 +0800 |
|---|---|---|
| committer | J-ZhengLi <lizheng135@huawei.com> | 2023-08-22 10:27:16 +0800 |
| commit | 77215672e9c29ad32eadcd65509738e21b714e86 (patch) | |
| tree | 59a924181235b012d3c56fa0b05573b65952bf44 | |
| parent | fc1152abf6a3ab29e14d1d2d700eef64894ad494 (diff) | |
| download | rust-77215672e9c29ad32eadcd65509738e21b714e86.tar.gz rust-77215672e9c29ad32eadcd65509738e21b714e86.zip | |
fix [`undocumented_unsafe_blocks`] not able to detect comment for global vars
| -rw-r--r-- | clippy_lints/src/undocumented_unsafe_blocks.rs | 113 | ||||
| -rw-r--r-- | tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs | 14 |
2 files changed, 65 insertions, 62 deletions
diff --git a/clippy_lints/src/undocumented_unsafe_blocks.rs b/clippy_lints/src/undocumented_unsafe_blocks.rs index f2ef602012f..4ee817c0676 100644 --- a/clippy_lints/src/undocumented_unsafe_blocks.rs +++ b/clippy_lints/src/undocumented_unsafe_blocks.rs @@ -341,44 +341,21 @@ fn block_parents_have_safety_comment( id: hir::HirId, ) -> bool { if let Some(node) = get_parent_node(cx.tcx, id) { - return match node { - 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) - { - let hir_id = match get_parent_node(cx.tcx, expr.hir_id) { - Some(Node::Local(hir::Local { hir_id, .. })) => *hir_id, - Some(Node::Item(hir::Item { owner_id, .. })) => { - cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id) - }, - _ => unreachable!(), - }; - - // 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_with_attrs_in_body_has_safety_comment( - cx, - *span, - hir_id, - accept_comment_above_attributes, - ) - } else { - !is_branchy(expr) - && span_with_attrs_in_body_has_safety_comment( - cx, - expr.span, - expr.hir_id, - accept_comment_above_attributes, - ) - } + let (span, hir_id) = match node { + Node::Expr(expr) => match get_parent_node(cx.tcx, expr.hir_id) { + Some(Node::Local(hir::Local { span, hir_id, .. })) => (*span, *hir_id), + Some(Node::Item(hir::Item { + kind: hir::ItemKind::Const(..) | ItemKind::Static(..), + span, + owner_id, + .. + })) => (*span, cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id)), + _ => { + if is_branchy(expr) { + return false; + } + (expr.span, expr.hir_id) + }, }, Node::Stmt(hir::Stmt { kind: @@ -387,28 +364,27 @@ fn block_parents_have_safety_comment( | hir::StmtKind::Semi(hir::Expr { span, hir_id, .. }), .. }) - | Node::Local(hir::Local { span, hir_id, .. }) => { - span_with_attrs_in_body_has_safety_comment(cx, *span, *hir_id, accept_comment_above_attributes) - }, + | Node::Local(hir::Local { span, hir_id, .. }) => (*span, *hir_id), Node::Item(hir::Item { kind: hir::ItemKind::Const(..) | ItemKind::Static(..), span, owner_id, .. - }) => span_with_attrs_in_body_has_safety_comment( - cx, - *span, - cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id), - accept_comment_above_attributes, - ), - _ => false, + }) => (*span, cx.tcx.hir().local_def_id_to_hir_id(owner_id.def_id)), + _ => return false, }; + // 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_with_attrs_has_safety_comment(cx, span, hir_id, accept_comment_above_attributes) + } else { + false } - false } /// Extends `span` to also include its attributes, then checks if that span has a safety comment. -fn span_with_attrs_in_body_has_safety_comment( +fn span_with_attrs_has_safety_comment( cx: &LateContext<'_>, span: Span, hir_id: HirId, @@ -420,7 +396,7 @@ fn span_with_attrs_in_body_has_safety_comment( span }; - span_in_body_has_safety_comment(cx, span) + span_has_safety_comment(cx, span) } /// Checks if an expression is "branchy", e.g. loop, match/if/etc. @@ -444,7 +420,7 @@ fn block_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { matches!( span_from_macro_expansion_has_safety_comment(cx, span), HasSafetyComment::Yes(_) - ) || span_in_body_has_safety_comment(cx, span) + ) || span_has_safety_comment(cx, span) } fn include_attrs_in_span(cx: &LateContext<'_>, hir_id: HirId, span: Span) -> Span { @@ -639,29 +615,42 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> { let body = cx.enclosing_body?; let map = cx.tcx.hir(); let mut span = map.body(body).value.span; + let mut maybe_global_var = false; for (_, node) in map.parent_iter(body.hir_id) { match node { - Node::Expr(e) => span = e.span, + Node::Expr(e) => { + span = e.span; + // Note: setting this to `false` is to making sure a "in-function defined" + // const/static variable not mistakenly processed as global variable, + // since global var doesn't have an `Expr` parent as its parent??? + maybe_global_var = false; + } Node::Block(_) | Node::Arm(_) | Node::Stmt(_) - | Node::Local(_) - | Node::Item(hir::Item { - kind: hir::ItemKind::Const(..) | ItemKind::Static(..), - .. - }) => (), + | Node::Local(_) => (), + Node::Item(hir::Item { kind, span: item_span, .. }) => { + if matches!(kind, hir::ItemKind::Const(..) | ItemKind::Static(..)) { + maybe_global_var = true; + } else if maybe_global_var && let hir::ItemKind::Mod(_) = kind { + span = *item_span; + } else { + break; + } + } + Node::Crate(mod_) if maybe_global_var => { + span = mod_.spans.inner_span; + } _ => break, } } Some(span) } -fn span_in_body_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { +fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool { let source_map = cx.sess().source_map(); let ctxt = span.ctxt(); - if ctxt == SyntaxContext::root() - && let Some(search_span) = get_body_search_span(cx) - { + if ctxt.is_root() && let Some(search_span) = get_body_search_span(cx) { if let Ok(unsafe_line) = source_map.lookup_line(span.lo()) && let Some(body_span) = walk_span_to_context(search_span, SyntaxContext::root()) && let Ok(body_line) = source_map.lookup_line(body_span.lo()) diff --git a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs index c0976f0d600..a28cf9efbbc 100644 --- a/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs +++ b/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs @@ -564,4 +564,18 @@ fn issue_8679<T: Copy>() { unsafe {} } +mod issue_11246 { + // Safety: foo + const _: () = unsafe {}; + + // Safety: A safety comment + const FOO: () = unsafe {}; + + // Safety: bar + static BAR: u8 = unsafe { 0 }; +} + +// Safety: Another safety comment +const FOO: () = unsafe {}; + fn main() {} |
