Skip to content

Commit c85450b

Browse files
committed
some refractoring + reduce code repetition
1 parent c6e1f5b commit c85450b

File tree

1 file changed

+65
-136
lines changed

1 file changed

+65
-136
lines changed

clippy_lints/src/undocumented_unsafe_blocks.rs

Lines changed: 65 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,10 @@ use clippy_utils::diagnostics::span_lint_and_help;
44
use clippy_utils::source::walk_span_to_context;
55
use clippy_utils::visitors::{for_each_expr_with_closures, Descend};
66
use clippy_utils::{get_parent_node, is_lint_allowed};
7+
use hir::OwnerId;
78
use rustc_data_structures::sync::Lrc;
89
use rustc_hir as hir;
9-
use rustc_hir::{Block, BlockCheckMode, HirId, ItemKind, Node, OwnerNode, UnsafeSource};
10+
use rustc_hir::{Block, BlockCheckMode, HirId, ItemKind, Node, UnsafeSource};
1011
use rustc_lexer::{tokenize, TokenKind};
1112
use rustc_lint::{LateContext, LateLintPass, LintContext};
1213
use rustc_middle::lint::in_external_macro;
@@ -263,59 +264,43 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
263264
// NB: This does not check undocumented unsafe block as they are handled
264265
// by `check_block` and `block_parents_have_safety_comment`
265266
fn check_trait_item(&mut self, cx: &LateContext<'_>, trait_item: &hir::TraitItem<'_>) {
266-
if in_external_macro(cx.tcx.sess, trait_item.span)
267-
|| is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, trait_item.hir_id())
268-
{
269-
return;
270-
}
271-
272-
let hir::TraitItemKind::Const(_, Some(body_id)) = trait_item.kind else {
267+
let hir::TraitItemKind::Const(..) = trait_item.kind else {
273268
return;
274269
};
275-
if body_is_unsafe_block(cx, body_id) {
276-
return;
277-
}
278-
279-
if let HasSafetyComment::Yes(pos) = item_has_safety_comment(cx, trait_item.hir_id(), trait_item.into()) {
280-
let (span, help_span) = mk_spans(cx, trait_item.span, pos);
281-
span_lint_and_help(
282-
cx,
283-
UNNECESSARY_SAFETY_COMMENT,
284-
span,
285-
"associated constant has unnecessary safety comment",
286-
Some(help_span),
287-
"consider removing the safety comment",
288-
);
289-
}
270+
lint_usc_on_associated_consts(cx, trait_item, trait_item.hir_id());
290271
}
291272

292273
// Check unnecessary unsafe comment above impl items.
293274
// NB: Same as [`check_trait_item`] above, this does not check undocumented unsafe block.
294275
fn check_impl_item(&mut self, cx: &LateContext<'_>, impl_item: &hir::ImplItem<'_>) {
295-
if in_external_macro(cx.tcx.sess, impl_item.span)
296-
|| is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, impl_item.hir_id())
297-
{
298-
return;
299-
}
300-
301-
let hir::ImplItemKind::Const(_, body_id) = impl_item.kind else {
276+
let hir::ImplItemKind::Const(..) = impl_item.kind else {
302277
return;
303278
};
304-
if body_is_unsafe_block(cx, body_id) {
305-
return;
306-
}
279+
lint_usc_on_associated_consts(cx, impl_item, impl_item.hir_id());
280+
}
281+
}
307282

308-
if let HasSafetyComment::Yes(pos) = item_has_safety_comment(cx, impl_item.hir_id(), impl_item.into()) {
309-
let (span, help_span) = mk_spans(cx, impl_item.span, pos);
310-
span_lint_and_help(
311-
cx,
312-
UNNECESSARY_SAFETY_COMMENT,
313-
span,
314-
"associated constant has unnecessary safety comment",
315-
Some(help_span),
316-
"consider removing the safety comment",
317-
);
318-
}
283+
fn lint_usc_on_associated_consts<'hir, T: Into<hir::OwnerNode<'hir>>>(cx: &LateContext<'_>, item: T, hir_id: HirId) {
284+
let owner_node = item.into();
285+
let span = owner_node.span();
286+
let Some(body_id) = owner_node.body_id() else { return };
287+
if in_external_macro(cx.tcx.sess, span)
288+
|| is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, hir_id)
289+
|| body_is_unsafe_block(cx, body_id)
290+
{
291+
return;
292+
}
293+
294+
if let HasSafetyComment::Yes(pos) = item_has_safety_comment(cx, hir_id, owner_node) {
295+
let (span, help_span) = mk_spans(cx, span, pos);
296+
span_lint_and_help(
297+
cx,
298+
UNNECESSARY_SAFETY_COMMENT,
299+
span,
300+
"associated constant has unnecessary safety comment",
301+
Some(help_span),
302+
"consider removing the safety comment",
303+
);
319304
}
320305
}
321306

@@ -524,25 +509,34 @@ fn item_has_safety_comment(cx: &LateContext<'_>, hir_id: HirId, owner: hir::Owne
524509
has_safety_comment => return has_safety_comment,
525510
}
526511

527-
if owner.span().ctxt() != SyntaxContext::root() {
512+
if owner.span().from_expansion() {
528513
return HasSafetyComment::No;
529514
}
530515
if let Some(parent_node) = get_parent_node(cx.tcx, hir_id) {
531516
let comment_start = match parent_node {
532-
Node::Crate(parent_mod) => {
533-
comment_start_pos_in_parent_context(cx, parent_mod.item_ids, parent_mod.spans.inner_span, owner)
534-
},
517+
Node::Crate(parent_mod) => comment_start_pos(
518+
cx,
519+
parent_mod.item_ids.iter().map(|id| id.owner_id),
520+
parent_mod.spans.inner_span,
521+
owner.def_id(),
522+
),
535523
Node::Item(parent_item) => {
536524
match parent_item.kind {
537-
ItemKind::Mod(parent_mod) => {
538-
comment_start_pos_in_parent_context(cx, parent_mod.item_ids, parent_item.span, owner)
539-
},
525+
ItemKind::Mod(parent_mod) => comment_start_pos(
526+
cx,
527+
parent_mod.item_ids.iter().map(|id| id.owner_id),
528+
parent_item.span,
529+
owner.def_id(),
530+
),
540531
ItemKind::Trait(_, _, _, _, refs) => {
541-
comment_start_pos_in_parent_context(cx, refs, parent_item.span, owner)
542-
},
543-
ItemKind::Impl(hir::Impl { items, .. }) => {
544-
comment_start_pos_in_parent_context(cx, items, parent_item.span, owner)
532+
comment_start_pos(cx, refs.iter().map(|r| r.id.owner_id), parent_item.span, owner.def_id())
545533
},
534+
ItemKind::Impl(hir::Impl { items, .. }) => comment_start_pos(
535+
cx,
536+
items.iter().map(|r| r.id.owner_id),
537+
parent_item.span,
538+
owner.def_id(),
539+
),
546540
// Doesn't support impls in this position. Pretend a comment was found.
547541
_ => return HasSafetyComment::Maybe,
548542
}
@@ -627,71 +621,20 @@ fn stmt_has_safety_comment(cx: &LateContext<'_>, span: Span, hir_id: HirId) -> H
627621
HasSafetyComment::Maybe
628622
}
629623

630-
trait CheckableItemId {
631-
fn owner_id(&self) -> hir::OwnerId;
632-
}
633-
634-
impl CheckableItemId for hir::ItemId {
635-
fn owner_id(&self) -> hir::OwnerId {
636-
self.owner_id
637-
}
638-
}
639-
impl CheckableItemId for hir::ImplItemRef {
640-
fn owner_id(&self) -> hir::OwnerId {
641-
self.id.owner_id
642-
}
643-
}
644-
impl CheckableItemId for hir::TraitItemRef {
645-
fn owner_id(&self) -> hir::OwnerId {
646-
self.id.owner_id
647-
}
648-
}
649-
650624
/// Search and return the starting [`BytePos`] of the comment above an 'item' in its context.
651-
fn comment_start_pos_in_parent_context<T: CheckableItemId>(
625+
fn comment_start_pos<I: Iterator<Item = OwnerId> + DoubleEndedIterator>(
652626
cx: &LateContext<'_>,
653-
ids: &[T],
627+
mut siblings: I,
654628
search_span: Span,
655-
owner: OwnerNode<'_>,
629+
owner_id: OwnerId,
656630
) -> Option<BytePos> {
657-
let map = cx.tcx.hir();
658-
ids.iter().enumerate().find_map(|(idx, id)| {
659-
if id.owner_id() == owner.def_id() {
660-
if idx == 0 {
661-
// mod A { /* comment */ unsafe impl T {} ... }
662-
// ^------------------------------------------^ returns the start of this span
663-
// ^---------------------^ finally checks comments in this range
664-
walk_span_to_context(search_span, SyntaxContext::root()).map(Span::lo)
665-
} else {
666-
// some_item /* comment */ unsafe impl T {}
667-
// ^-------^ returns the end of this span
668-
// ^---------------^ finally checks comments in this range
669-
match owner {
670-
OwnerNode::Item(_) => {
671-
let prev_item = map.item(hir::ItemId {
672-
owner_id: ids[idx - 1].owner_id(),
673-
});
674-
walk_span_to_context(prev_item.span, SyntaxContext::root()).map(Span::lo)
675-
},
676-
OwnerNode::ImplItem(_) => {
677-
let prev_impl_item = map.impl_item(hir::ImplItemId {
678-
owner_id: ids[idx - 1].owner_id(),
679-
});
680-
walk_span_to_context(prev_impl_item.span, SyntaxContext::root()).map(Span::lo)
681-
},
682-
OwnerNode::TraitItem(_) => {
683-
let prev_trait_item = map.trait_item(hir::TraitItemId {
684-
owner_id: ids[idx - 1].owner_id(),
685-
});
686-
walk_span_to_context(prev_trait_item.span, SyntaxContext::root()).map(Span::lo)
687-
},
688-
_ => None,
689-
}
690-
}
691-
} else {
692-
None
693-
}
694-
})
631+
let _ = siblings.rfind(|id| *id == owner_id);
632+
if let Some(prev_sibling_id) = siblings.next_back() {
633+
let prev_sibling_span = cx.tcx.hir().span(prev_sibling_id.into());
634+
walk_span_to_context(prev_sibling_span, SyntaxContext::root()).map(Span::lo)
635+
} else {
636+
walk_span_to_context(search_span, SyntaxContext::root()).map(Span::lo)
637+
}
695638
}
696639

697640
fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span) -> HasSafetyComment {
@@ -730,13 +673,8 @@ fn span_from_macro_expansion_has_safety_comment(cx: &LateContext<'_>, span: Span
730673

731674
fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
732675
let body = cx.enclosing_body?;
733-
let map = cx.tcx.hir();
734-
let mut span = map.body(body).value.span;
735-
let mut is_const_or_static = false;
736-
for (_, parent_node) in map.parent_iter(body.hir_id) {
676+
for (_, parent_node) in cx.tcx.hir().parent_iter(body.hir_id) {
737677
match parent_node {
738-
Node::Expr(e) => span = e.span,
739-
Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::Local(_) => (),
740678
Node::Item(hir::Item {
741679
kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
742680
..
@@ -748,22 +686,13 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
748686
| Node::TraitItem(hir::TraitItem {
749687
kind: hir::TraitItemKind::Const(..),
750688
..
751-
}) => is_const_or_static = true,
752-
// Parent is a `mod xxx { .. }``
753-
Node::Item(item) => {
754-
match item.kind {
755-
ItemKind::Mod(_) | ItemKind::Trait(..) | ItemKind::Impl(..) => span = item.span,
756-
_ => (),
757-
}
758-
break;
759-
},
760-
Node::Crate(mod_) if is_const_or_static => {
761-
span = mod_.spans.inner_span;
762-
},
763-
_ => break,
689+
}) => {},
690+
Node::Item(item) => return Some(item.span),
691+
Node::Crate(mod_) => return Some(mod_.spans.inner_span),
692+
_ => {},
764693
}
765694
}
766-
Some(span)
695+
None
767696
}
768697

769698
fn span_has_safety_comment(cx: &LateContext<'_>, span: Span) -> bool {

0 commit comments

Comments
 (0)