1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
use rustc_middle::ty::{TyCtxt, Visibility};

use crate::clean;
use crate::clean::Item;
use crate::core::DocContext;
use crate::fold::{strip_item, DocFolder};
use crate::passes::Pass;

pub(crate) const STRIP_ALIASED_NON_LOCAL: Pass = Pass {
    name: "strip-aliased-non-local",
    run: strip_aliased_non_local,
    description: "strips all non-local private aliased items from the output",
};

fn strip_aliased_non_local(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
    let mut stripper = AliasedNonLocalStripper { tcx: cx.tcx };
    stripper.fold_crate(krate)
}

struct AliasedNonLocalStripper<'tcx> {
    tcx: TyCtxt<'tcx>,
}

impl<'tcx> DocFolder for AliasedNonLocalStripper<'tcx> {
    fn fold_item(&mut self, i: Item) -> Option<Item> {
        Some(match *i.kind {
            clean::TypeAliasItem(..) => {
                let mut stripper = NonLocalStripper { tcx: self.tcx };
                // don't call `fold_item` as that could strip the type-alias it-self
                // which we don't want to strip out
                stripper.fold_item_recur(i)
            }
            _ => self.fold_item_recur(i),
        })
    }
}

struct NonLocalStripper<'tcx> {
    tcx: TyCtxt<'tcx>,
}

impl<'tcx> DocFolder for NonLocalStripper<'tcx> {
    fn fold_item(&mut self, i: Item) -> Option<Item> {
        // If not local, we want to respect the original visibility of
        // the field and not the one given by the user for the currrent crate.
        //
        // FIXME(#125009): Not-local should probably consider same Cargo workspace
        if let Some(def_id) = i.def_id()
            && !def_id.is_local()
        {
            if i.is_doc_hidden()
                // Default to *not* stripping items with inherited visibility.
                || i.visibility(self.tcx).map_or(false, |viz| viz != Visibility::Public)
            {
                return Some(strip_item(i));
            }
        }

        Some(self.fold_item_recur(i))
    }
}