Take &mut DocContext in passes
This should hopefully allow for less interior mutability.
This commit is contained in:
parent
8fe989dd76
commit
6da9e3c226
14 changed files with 49 additions and 83 deletions
|
|
@ -627,7 +627,7 @@ crate fn run_global_ctxt(
|
|||
};
|
||||
if run {
|
||||
debug!("running pass {}", p.pass.name);
|
||||
krate = ctxt.tcx.sess.time(p.pass.name, || (p.pass.run)(krate, &ctxt));
|
||||
krate = ctxt.tcx.sess.time(p.pass.name, || (p.pass.run)(krate, &mut ctxt));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ crate const CALCULATE_DOC_COVERAGE: Pass = Pass {
|
|||
description: "counts the number of items with and without documentation",
|
||||
};
|
||||
|
||||
fn calculate_doc_coverage(krate: clean::Crate, ctx: &DocContext<'_>) -> clean::Crate {
|
||||
let mut calc = CoverageCalculator::new(ctx);
|
||||
fn calculate_doc_coverage(krate: clean::Crate, ctx: &mut DocContext<'_>) -> clean::Crate {
|
||||
let mut calc = CoverageCalculator { items: Default::default(), ctx };
|
||||
let krate = calc.fold_crate(krate);
|
||||
|
||||
calc.print_results();
|
||||
|
|
@ -101,7 +101,7 @@ impl ops::AddAssign for ItemCount {
|
|||
|
||||
struct CoverageCalculator<'a, 'b> {
|
||||
items: BTreeMap<FileName, ItemCount>,
|
||||
ctx: &'a DocContext<'b>,
|
||||
ctx: &'a mut DocContext<'b>,
|
||||
}
|
||||
|
||||
fn limit_filename_len(filename: String) -> String {
|
||||
|
|
@ -115,10 +115,6 @@ fn limit_filename_len(filename: String) -> String {
|
|||
}
|
||||
|
||||
impl<'a, 'b> CoverageCalculator<'a, 'b> {
|
||||
fn new(ctx: &'a DocContext<'b>) -> CoverageCalculator<'a, 'b> {
|
||||
CoverageCalculator { items: Default::default(), ctx }
|
||||
}
|
||||
|
||||
fn to_json(&self) -> String {
|
||||
serde_json::to_string(
|
||||
&self
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ crate const CHECK_CODE_BLOCK_SYNTAX: Pass = Pass {
|
|||
description: "validates syntax inside Rust code blocks",
|
||||
};
|
||||
|
||||
crate fn check_code_block_syntax(krate: clean::Crate, cx: &DocContext<'_>) -> clean::Crate {
|
||||
crate fn check_code_block_syntax(krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
|
||||
SyntaxChecker { cx }.fold_crate(krate)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -47,8 +47,13 @@ crate const COLLECT_INTRA_DOC_LINKS: Pass = Pass {
|
|||
description: "resolves intra-doc links",
|
||||
};
|
||||
|
||||
crate fn collect_intra_doc_links(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
LinkCollector::new(cx).fold_crate(krate)
|
||||
crate fn collect_intra_doc_links(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
LinkCollector {
|
||||
cx,
|
||||
mod_ids: Vec::new(),
|
||||
kind_side_channel: Cell::new(None),
|
||||
visited_links: FxHashMap::default(),
|
||||
}.fold_crate(krate)
|
||||
}
|
||||
|
||||
/// Top-level errors emitted by this pass.
|
||||
|
|
@ -257,7 +262,7 @@ struct CachedLink {
|
|||
}
|
||||
|
||||
struct LinkCollector<'a, 'tcx> {
|
||||
cx: &'a DocContext<'tcx>,
|
||||
cx: &'a mut DocContext<'tcx>,
|
||||
/// A stack of modules used to decide what scope to resolve in.
|
||||
///
|
||||
/// The last module will be used if the parent scope of the current item is
|
||||
|
|
@ -273,15 +278,6 @@ struct LinkCollector<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
||||
fn new(cx: &'a DocContext<'tcx>) -> Self {
|
||||
LinkCollector {
|
||||
cx,
|
||||
mod_ids: Vec::new(),
|
||||
kind_side_channel: Cell::new(None),
|
||||
visited_links: FxHashMap::default(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Given a full link, parse it as an [enum struct variant].
|
||||
///
|
||||
/// In particular, this will return an error whenever there aren't three
|
||||
|
|
@ -293,7 +289,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
path_str: &'path str,
|
||||
module_id: DefId,
|
||||
) -> Result<(Res, Option<String>), ErrorKind<'path>> {
|
||||
let cx = self.cx;
|
||||
let tcx = self.cx.tcx;
|
||||
let no_res = || ResolutionFailure::NotResolved {
|
||||
module_id,
|
||||
partial_res: None,
|
||||
|
|
@ -317,7 +313,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
// If there's no third component, we saw `[a::b]` before and it failed to resolve.
|
||||
// So there's no partial res.
|
||||
.ok_or_else(no_res)?;
|
||||
let ty_res = cx
|
||||
let ty_res = self.cx
|
||||
.enter_resolver(|resolver| {
|
||||
resolver.resolve_str_path_error(DUMMY_SP, &path, TypeNS, module_id)
|
||||
})
|
||||
|
|
@ -326,18 +322,17 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
|
||||
match ty_res {
|
||||
Res::Def(DefKind::Enum, did) => {
|
||||
if cx
|
||||
.tcx
|
||||
if tcx
|
||||
.inherent_impls(did)
|
||||
.iter()
|
||||
.flat_map(|imp| cx.tcx.associated_items(*imp).in_definition_order())
|
||||
.flat_map(|imp| tcx.associated_items(*imp).in_definition_order())
|
||||
.any(|item| item.ident.name == variant_name)
|
||||
{
|
||||
// This is just to let `fold_item` know that this shouldn't be considered;
|
||||
// it's a bug for the error to make it to the user
|
||||
return Err(ResolutionFailure::Dummy.into());
|
||||
}
|
||||
match cx.tcx.type_of(did).kind() {
|
||||
match tcx.type_of(did).kind() {
|
||||
ty::Adt(def, _) if def.is_enum() => {
|
||||
if def.all_fields().any(|item| item.ident.name == variant_field_name) {
|
||||
Ok((
|
||||
|
|
@ -380,16 +375,16 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
item_name: Symbol,
|
||||
item_str: &'path str,
|
||||
) -> Result<(Res, Option<String>), ErrorKind<'path>> {
|
||||
let cx = self.cx;
|
||||
let tcx = self.cx.tcx;
|
||||
|
||||
prim_ty
|
||||
.impls(cx.tcx)
|
||||
.impls(tcx)
|
||||
.into_iter()
|
||||
.find_map(|&impl_| {
|
||||
cx.tcx
|
||||
tcx
|
||||
.associated_items(impl_)
|
||||
.find_by_name_and_namespace(
|
||||
cx.tcx,
|
||||
tcx,
|
||||
Ident::with_dummy_span(item_name),
|
||||
ns,
|
||||
impl_,
|
||||
|
|
@ -434,9 +429,8 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
path_str: &'a str,
|
||||
module_id: DefId,
|
||||
) -> Result<Res, ResolutionFailure<'a>> {
|
||||
let cx = self.cx;
|
||||
let path = ast::Path::from_ident(Ident::from_str(path_str));
|
||||
cx.enter_resolver(|resolver| {
|
||||
self.cx.enter_resolver(|resolver| {
|
||||
// FIXME(jynelson): does this really need 3 separate lookups?
|
||||
if let Ok((Some(ext), res)) = resolver.resolve_macro_path(
|
||||
&path,
|
||||
|
|
@ -498,7 +492,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
|
|||
module_id: DefId,
|
||||
extra_fragment: &Option<String>,
|
||||
) -> Result<(Res, Option<String>), ErrorKind<'path>> {
|
||||
let cx = self.cx;
|
||||
let cx = &self.cx;
|
||||
|
||||
if let Some(res) = self.resolve_path(path_str, ns, module_id) {
|
||||
match res {
|
||||
|
|
@ -948,12 +942,11 @@ impl LinkCollector<'_, '_> {
|
|||
return None;
|
||||
}
|
||||
|
||||
let cx = self.cx;
|
||||
let link = ori_link.link.replace("`", "");
|
||||
let parts = link.split('#').collect::<Vec<_>>();
|
||||
let (link, extra_fragment) = if parts.len() > 2 {
|
||||
// A valid link can't have multiple #'s
|
||||
anchor_failure(cx, &item, &link, dox, ori_link.range, AnchorFailure::MultipleAnchors);
|
||||
anchor_failure(self.cx, &item, &link, dox, ori_link.range, AnchorFailure::MultipleAnchors);
|
||||
return None;
|
||||
} else if parts.len() == 2 {
|
||||
if parts[0].trim().is_empty() {
|
||||
|
|
@ -1105,7 +1098,7 @@ impl LinkCollector<'_, '_> {
|
|||
if matches!(disambiguator, Some(Disambiguator::Primitive)) {
|
||||
if fragment.is_some() {
|
||||
anchor_failure(
|
||||
cx,
|
||||
self.cx,
|
||||
&item,
|
||||
path_str,
|
||||
dox,
|
||||
|
|
@ -1119,7 +1112,7 @@ impl LinkCollector<'_, '_> {
|
|||
} else {
|
||||
// `[char]` when a `char` module is in scope
|
||||
let candidates = vec![res, prim];
|
||||
ambiguity_error(cx, &item, path_str, dox, ori_link.range, candidates);
|
||||
ambiguity_error(self.cx, &item, path_str, dox, ori_link.range, candidates);
|
||||
return None;
|
||||
}
|
||||
}
|
||||
|
|
@ -1140,7 +1133,7 @@ impl LinkCollector<'_, '_> {
|
|||
suggest_disambiguator(resolved, diag, path_str, dox, sp, &ori_link.range);
|
||||
};
|
||||
report_diagnostic(
|
||||
cx,
|
||||
self.cx,
|
||||
BROKEN_INTRA_DOC_LINKS,
|
||||
&msg,
|
||||
&item,
|
||||
|
|
@ -1187,7 +1180,7 @@ impl LinkCollector<'_, '_> {
|
|||
if self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_src)
|
||||
&& !self.cx.tcx.privacy_access_levels(LOCAL_CRATE).is_exported(hir_dst)
|
||||
{
|
||||
privacy_error(cx, &item, &path_str, dox, &ori_link);
|
||||
privacy_error(self.cx, &item, &path_str, dox, &ori_link);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1211,7 +1204,7 @@ impl LinkCollector<'_, '_> {
|
|||
&& !self.cx.tcx.features().intra_doc_pointers
|
||||
{
|
||||
let span = super::source_span_for_markdown_range(
|
||||
cx,
|
||||
self.cx,
|
||||
dox,
|
||||
&ori_link.range,
|
||||
&item.attrs,
|
||||
|
|
@ -1243,7 +1236,7 @@ impl LinkCollector<'_, '_> {
|
|||
}
|
||||
Res::Def(kind, id) => {
|
||||
verify(kind, id)?;
|
||||
let id = clean::register_res(cx, rustc_hir::def::Res::Def(kind, id));
|
||||
let id = clean::register_res(self.cx, rustc_hir::def::Res::Def(kind, id));
|
||||
Some(ItemLink { link: ori_link.link, link_text, did: Some(id), fragment })
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@ crate const COLLECT_TRAIT_IMPLS: Pass = Pass {
|
|||
description: "retrieves trait impls for items in the crate",
|
||||
};
|
||||
|
||||
crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
let mut synth = SyntheticImplCollector::new(cx);
|
||||
crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
let mut synth = SyntheticImplCollector { cx, impls: Vec::new() };
|
||||
let mut krate = cx.sess().time("collect_synthetic_impls", || synth.fold_crate(krate));
|
||||
|
||||
let prims: FxHashSet<PrimitiveType> = krate.primitives.iter().map(|p| p.1).collect();
|
||||
|
|
@ -164,12 +164,6 @@ struct SyntheticImplCollector<'a, 'tcx> {
|
|||
impls: Vec<Item>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> SyntheticImplCollector<'a, 'tcx> {
|
||||
fn new(cx: &'a DocContext<'tcx>) -> Self {
|
||||
SyntheticImplCollector { cx, impls: Vec::new() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DocFolder for SyntheticImplCollector<'a, 'tcx> {
|
||||
fn fold_item(&mut self, i: Item) -> Option<Item> {
|
||||
if i.is_struct() || i.is_enum() || i.is_union() {
|
||||
|
|
|
|||
|
|
@ -19,27 +19,20 @@ crate const CHECK_PRIVATE_ITEMS_DOC_TESTS: Pass = Pass {
|
|||
};
|
||||
|
||||
struct PrivateItemDocTestLinter<'a, 'tcx> {
|
||||
cx: &'a DocContext<'tcx>,
|
||||
cx: &'a mut DocContext<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> PrivateItemDocTestLinter<'a, 'tcx> {
|
||||
fn new(cx: &'a DocContext<'tcx>) -> Self {
|
||||
PrivateItemDocTestLinter { cx }
|
||||
}
|
||||
}
|
||||
|
||||
crate fn check_private_items_doc_tests(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
let mut coll = PrivateItemDocTestLinter::new(cx);
|
||||
crate fn check_private_items_doc_tests(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
let mut coll = PrivateItemDocTestLinter { cx };
|
||||
|
||||
coll.fold_crate(krate)
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> DocFolder for PrivateItemDocTestLinter<'a, 'tcx> {
|
||||
fn fold_item(&mut self, item: Item) -> Option<Item> {
|
||||
let cx = self.cx;
|
||||
let dox = item.attrs.collapsed_doc_value().unwrap_or_else(String::new);
|
||||
|
||||
look_for_tests(&cx, &dox, &item);
|
||||
look_for_tests(self.cx, &dox, &item);
|
||||
|
||||
Some(self.fold_item_recur(item))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -16,20 +16,14 @@ crate const CHECK_INVALID_HTML_TAGS: Pass = Pass {
|
|||
};
|
||||
|
||||
struct InvalidHtmlTagsLinter<'a, 'tcx> {
|
||||
cx: &'a DocContext<'tcx>,
|
||||
cx: &'a mut DocContext<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> InvalidHtmlTagsLinter<'a, 'tcx> {
|
||||
fn new(cx: &'a DocContext<'tcx>) -> Self {
|
||||
InvalidHtmlTagsLinter { cx }
|
||||
}
|
||||
}
|
||||
|
||||
crate fn check_invalid_html_tags(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
crate fn check_invalid_html_tags(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
if !cx.tcx.sess.is_nightly_build() {
|
||||
krate
|
||||
} else {
|
||||
let mut coll = InvalidHtmlTagsLinter::new(cx);
|
||||
let mut coll = InvalidHtmlTagsLinter { cx };
|
||||
|
||||
coll.fold_crate(krate)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ crate use self::html_tags::CHECK_INVALID_HTML_TAGS;
|
|||
#[derive(Copy, Clone)]
|
||||
crate struct Pass {
|
||||
crate name: &'static str,
|
||||
crate run: fn(clean::Crate, &DocContext<'_>) -> clean::Crate,
|
||||
crate run: fn(clean::Crate, &mut DocContext<'_>) -> clean::Crate,
|
||||
crate description: &'static str,
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,15 +23,11 @@ const URL_REGEX: &str = concat!(
|
|||
);
|
||||
|
||||
struct NonAutolinksLinter<'a, 'tcx> {
|
||||
cx: &'a DocContext<'tcx>,
|
||||
cx: &'a mut DocContext<'tcx>,
|
||||
regex: Regex,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> NonAutolinksLinter<'a, 'tcx> {
|
||||
fn new(cx: &'a DocContext<'tcx>) -> Self {
|
||||
Self { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") }
|
||||
}
|
||||
|
||||
fn find_raw_urls(
|
||||
&self,
|
||||
text: &str,
|
||||
|
|
@ -52,11 +48,11 @@ impl<'a, 'tcx> NonAutolinksLinter<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
crate fn check_non_autolinks(krate: Crate, cx: &DocContext<'_>) -> Crate {
|
||||
crate fn check_non_autolinks(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
|
||||
if !cx.tcx.sess.is_nightly_build() {
|
||||
krate
|
||||
} else {
|
||||
let mut coll = NonAutolinksLinter::new(cx);
|
||||
let mut coll = NonAutolinksLinter { cx, regex: Regex::new(URL_REGEX).expect("failed to build regex") };
|
||||
|
||||
coll.fold_crate(krate)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ crate const PROPAGATE_DOC_CFG: Pass = Pass {
|
|||
description: "propagates `#[doc(cfg(...))]` to child items",
|
||||
};
|
||||
|
||||
crate fn propagate_doc_cfg(cr: Crate, _: &DocContext<'_>) -> Crate {
|
||||
crate fn propagate_doc_cfg(cr: Crate, _: &mut DocContext<'_>) -> Crate {
|
||||
CfgPropagator { parent_cfg: None }.fold_crate(cr)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ crate const STRIP_HIDDEN: Pass = Pass {
|
|||
};
|
||||
|
||||
/// Strip items marked `#[doc(hidden)]`
|
||||
crate fn strip_hidden(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
|
||||
crate fn strip_hidden(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate {
|
||||
let mut retained = DefIdSet::default();
|
||||
|
||||
// strip all #[doc(hidden)] items
|
||||
|
|
|
|||
|
|
@ -9,6 +9,6 @@ crate const STRIP_PRIV_IMPORTS: Pass = Pass {
|
|||
description: "strips all private import statements (`use`, `extern crate`) from a crate",
|
||||
};
|
||||
|
||||
crate fn strip_priv_imports(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
|
||||
crate fn strip_priv_imports(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate {
|
||||
ImportStripper.fold_crate(krate)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ crate const STRIP_PRIVATE: Pass = Pass {
|
|||
|
||||
/// Strip private items from the point of view of a crate or externally from a
|
||||
/// crate, specified by the `xcrate` flag.
|
||||
crate fn strip_private(mut krate: clean::Crate, cx: &DocContext<'_>) -> clean::Crate {
|
||||
crate fn strip_private(mut krate: clean::Crate, cx: &mut DocContext<'_>) -> clean::Crate {
|
||||
// This stripper collects all *retained* nodes.
|
||||
let mut retained = DefIdSet::default();
|
||||
let access_levels = cx.renderinfo.borrow().access_levels.clone();
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ crate const UNINDENT_COMMENTS: Pass = Pass {
|
|||
description: "removes excess indentation on comments in order for markdown to like it",
|
||||
};
|
||||
|
||||
crate fn unindent_comments(krate: clean::Crate, _: &DocContext<'_>) -> clean::Crate {
|
||||
crate fn unindent_comments(krate: clean::Crate, _: &mut DocContext<'_>) -> clean::Crate {
|
||||
CommentCleaner.fold_crate(krate)
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue