Skip to main content

rustdoc/passes/
lint.rs

1//! Runs several rustdoc lints, consolidating them into a single pass for efficiency and simplicity.
2
3mod bare_urls;
4mod check_code_block_syntax;
5mod footnotes;
6mod html_tags;
7mod invalid_markdown_table;
8mod redundant_explicit_links;
9mod unescaped_backticks;
10
11use crate::clean::*;
12use crate::core::DocContext;
13use crate::visit::DocVisitor;
14
15struct Linter<'a, 'tcx> {
16    cx: &'a mut DocContext<'tcx>,
17}
18
19pub(super) fn lint(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
20    Linter { cx }.visit_crate(&krate);
21    krate
22}
23
24impl DocVisitor<'_> for Linter<'_, '_> {
25    fn visit_item(&mut self, item: &Item) {
26        let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.item_id) else {
27            // If non-local, no need to check anything.
28            return;
29        };
30        let dox = item.doc_value();
31        if !dox.is_empty() {
32            let may_have_link = dox.contains(&[':', '['][..]);
33            let may_have_block_comment_or_html = dox.contains(['<', '>']);
34            let may_have_table = dox.contains(&['|'][..]);
35            // ~~~rust
36            // // This is a real, supported commonmark syntax for block code
37            // ~~~
38            let may_have_code = dox.contains(&['~', '`', '\t'][..]) || dox.contains("    ");
39            if may_have_link {
40                bare_urls::visit_item(self.cx, item, hir_id, &dox);
41                redundant_explicit_links::visit_item(self.cx, item, hir_id);
42                footnotes::visit_item(self.cx, item, hir_id, &dox);
43            }
44            if may_have_code {
45                check_code_block_syntax::visit_item(self.cx, item, &dox);
46                unescaped_backticks::visit_item(self.cx, item, hir_id, &dox);
47            }
48            if may_have_block_comment_or_html {
49                html_tags::visit_item(self.cx, item, hir_id, &dox);
50            }
51            if may_have_table {
52                invalid_markdown_table::visit_item(self.cx, item, hir_id, &dox);
53            }
54        }
55
56        self.visit_item_recur(item)
57    }
58}