diff --git a/compiler/rustc_trait_selection/src/traits/auto_trait.rs b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
index 6593c1000f283..97cc258d42511 100644
--- a/compiler/rustc_trait_selection/src/traits/auto_trait.rs
+++ b/compiler/rustc_trait_selection/src/traits/auto_trait.rs
@@ -77,7 +77,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
         ty: Ty<'tcx>,
         orig_env: ty::ParamEnv<'tcx>,
         trait_did: DefId,
-        auto_trait_callback: impl Fn(&InferCtxt<'_, 'tcx>, AutoTraitInfo<'tcx>) -> A,
+        mut auto_trait_callback: impl FnMut(&InferCtxt<'_, 'tcx>, AutoTraitInfo<'tcx>) -> A,
     ) -> AutoTraitResult<A> {
         let tcx = self.tcx;
 
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 83114a72b8d5a..d43378081ce58 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -21,42 +21,38 @@ struct RegionDeps<'tcx> {
 }
 
 crate struct AutoTraitFinder<'a, 'tcx> {
-    crate cx: &'a core::DocContext<'tcx>,
-    crate f: auto_trait::AutoTraitFinder<'tcx>,
+    crate cx: &'a mut core::DocContext<'tcx>,
 }
 
 impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
-    crate fn new(cx: &'a core::DocContext<'tcx>) -> Self {
-        let f = auto_trait::AutoTraitFinder::new(cx.tcx);
-
-        AutoTraitFinder { cx, f }
+    crate fn new(cx: &'a mut core::DocContext<'tcx>) -> Self {
+        AutoTraitFinder { cx }
     }
 
     // FIXME(eddyb) figure out a better way to pass information about
     // parametrization of `ty` than `param_env_def_id`.
-    crate fn get_auto_trait_impls(&self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
-        let param_env = self.cx.tcx.param_env(param_env_def_id);
+    crate fn get_auto_trait_impls(&mut self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
+        let tcx = self.cx.tcx;
+        let param_env = tcx.param_env(param_env_def_id);
+        let f = auto_trait::AutoTraitFinder::new(self.cx.tcx);
 
         debug!("get_auto_trait_impls({:?})", ty);
-        let auto_traits = self.cx.auto_traits.iter().cloned();
+        let auto_traits: Vec<_> = self.cx.auto_traits.iter().cloned().collect();
         auto_traits
+            .into_iter()
             .filter_map(|trait_def_id| {
-                let trait_ref = ty::TraitRef {
-                    def_id: trait_def_id,
-                    substs: self.cx.tcx.mk_substs_trait(ty, &[]),
-                };
+                let trait_ref =
+                    ty::TraitRef { def_id: trait_def_id, substs: tcx.mk_substs_trait(ty, &[]) };
                 if !self.cx.generated_synthetics.borrow_mut().insert((ty, trait_def_id)) {
                     debug!("get_auto_trait_impl_for({:?}): already generated, aborting", trait_ref);
                     return None;
                 }
 
                 let result =
-                    self.f.find_auto_trait_generics(ty, param_env, trait_def_id, |infcx, info| {
+                    f.find_auto_trait_generics(ty, param_env, trait_def_id, |infcx, info| {
                         let region_data = info.region_data;
 
-                        let names_map = self
-                            .cx
-                            .tcx
+                        let names_map = tcx
                             .generics_of(param_env_def_id)
                             .params
                             .iter()
@@ -66,7 +62,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                             })
                             .map(|name| (name, Lifetime(name)))
                             .collect();
-                        let lifetime_predicates = self.handle_lifetimes(&region_data, &names_map);
+                        let lifetime_predicates = Self::handle_lifetimes(&region_data, &names_map);
                         let new_generics = self.param_env_to_generics(
                             infcx.tcx,
                             param_env_def_id,
@@ -105,12 +101,10 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                         // Instead, we generate `impl !Send for Foo<T>`, which better
                         // expresses the fact that `Foo<T>` never implements `Send`,
                         // regardless of the choice of `T`.
-                        let params = (
-                            self.cx.tcx.generics_of(param_env_def_id),
-                            ty::GenericPredicates::default(),
-                        )
-                            .clean(self.cx)
-                            .params;
+                        let params =
+                            (tcx.generics_of(param_env_def_id), ty::GenericPredicates::default())
+                                .clean(self.cx)
+                                .params;
 
                         Generics { params, where_predicates: Vec::new() }
                     }
@@ -139,12 +133,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
             .collect()
     }
 
-    fn get_lifetime(
-        &self,
-        region: Region<'_>,
-        names_map: &FxHashMap<Symbol, Lifetime>,
-    ) -> Lifetime {
-        self.region_name(region)
+    fn get_lifetime(region: Region<'_>, names_map: &FxHashMap<Symbol, Lifetime>) -> Lifetime {
+        region_name(region)
             .map(|name| {
                 names_map.get(&name).unwrap_or_else(|| {
                     panic!("Missing lifetime with name {:?} for {:?}", name.as_str(), region)
@@ -154,13 +144,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
             .clone()
     }
 
-    fn region_name(&self, region: Region<'_>) -> Option<Symbol> {
-        match region {
-            &ty::ReEarlyBound(r) => Some(r.name),
-            _ => None,
-        }
-    }
-
     // This method calculates two things: Lifetime constraints of the form 'a: 'b,
     // and region constraints of the form ReVar: 'a
     //
@@ -172,7 +155,6 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     // to perform the calculations we need on our own, rather than trying to make
     // existing inference/solver code do what we want.
     fn handle_lifetimes<'cx>(
-        &self,
         regions: &RegionConstraintData<'cx>,
         names_map: &FxHashMap<Symbol, Lifetime>,
     ) -> Vec<WherePredicate> {
@@ -210,9 +192,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 &Constraint::RegSubReg(r1, r2) => {
                     // The constraint is already in the form that we want, so we're done with it
                     // Desired order is 'larger, smaller', so flip then
-                    if self.region_name(r1) != self.region_name(r2) {
+                    if region_name(r1) != region_name(r2) {
                         finished
-                            .entry(self.region_name(r2).expect("no region_name found"))
+                            .entry(region_name(r2).expect("no region_name found"))
                             .or_default()
                             .push(r1);
                     }
@@ -245,9 +227,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                 for larger in deps.larger.iter() {
                     match (smaller, larger) {
                         (&RegionTarget::Region(r1), &RegionTarget::Region(r2)) => {
-                            if self.region_name(r1) != self.region_name(r2) {
+                            if region_name(r1) != region_name(r2) {
                                 finished
-                                    .entry(self.region_name(r2).expect("no region name found"))
+                                    .entry(region_name(r2).expect("no region name found"))
                                     .or_default()
                                     .push(r1) // Larger, smaller
                             }
@@ -292,7 +274,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                     .get(name)
                     .unwrap_or(&empty)
                     .iter()
-                    .map(|region| GenericBound::Outlives(self.get_lifetime(region, names_map)))
+                    .map(|region| GenericBound::Outlives(Self::get_lifetime(region, names_map)))
                     .collect();
 
                 if bounds.is_empty() {
@@ -437,7 +419,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     // K', we use the dedicated syntax 'T: Fn() -> K'
     // * We explicitly add a '?Sized' bound if we didn't find any 'Sized' predicates for a type
     fn param_env_to_generics(
-        &self,
+        &mut self,
         tcx: TyCtxt<'tcx>,
         param_env_def_id: DefId,
         param_env: ty::ParamEnv<'tcx>,
@@ -468,10 +450,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
                         _ => false,
                     }
             })
-            .map(|p| {
-                let replaced = p.fold_with(&mut replacer);
-                (replaced, replaced.clean(self.cx))
-            });
+            .map(|p| p.fold_with(&mut replacer));
 
         let mut generic_params =
             (tcx.generics_of(param_env_def_id), tcx.explicit_predicates_of(param_env_def_id))
@@ -490,7 +469,8 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
 
         let mut ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)> = Default::default();
 
-        for (orig_p, p) in clean_where_predicates {
+        for p in clean_where_predicates {
+            let (orig_p, p) = (p, p.clean(self.cx));
             if p.is_none() {
                 continue;
             }
@@ -749,6 +729,13 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
     }
 }
 
+fn region_name(region: Region<'_>) -> Option<Symbol> {
+    match region {
+        &ty::ReEarlyBound(r) => Some(r.name),
+        _ => None,
+    }
+}
+
 // Replaces all ReVars in a type with ty::Region's, using the provided map
 struct RegionReplacer<'a, 'tcx> {
     vid_to_region: &'a FxHashMap<ty::RegionVid, ty::Region<'tcx>>,
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index f1c26feea46ec..a9d19a725c44f 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -10,17 +10,13 @@ use rustc_span::DUMMY_SP;
 use super::*;
 
 crate struct BlanketImplFinder<'a, 'tcx> {
-    crate cx: &'a core::DocContext<'tcx>,
+    crate cx: &'a mut core::DocContext<'tcx>,
 }
 
 impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
-    crate fn new(cx: &'a core::DocContext<'tcx>) -> Self {
-        BlanketImplFinder { cx }
-    }
-
     // FIXME(eddyb) figure out a better way to pass information about
     // parametrization of `ty` than `param_env_def_id`.
-    crate fn get_blanket_impls(&self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
+    crate fn get_blanket_impls(&mut self, ty: Ty<'tcx>, param_env_def_id: DefId) -> Vec<Item> {
         let param_env = self.cx.tcx.param_env(param_env_def_id);
 
         debug!("get_blanket_impls({:?})", ty);
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index cacca542284d9..fded0499ba6a8 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -37,7 +37,7 @@ type Attrs<'hir> = rustc_middle::ty::Attributes<'hir>;
 ///
 /// `parent_module` refers to the parent of the *re-export*, not the original item.
 crate fn try_inline(
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
     parent_module: DefId,
     res: Res,
     name: Symbol,
@@ -129,7 +129,7 @@ crate fn try_inline(
 }
 
 crate fn try_inline_glob(
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
     res: Res,
     visited: &mut FxHashSet<DefId>,
 ) -> Option<Vec<clean::Item>> {
@@ -187,7 +187,7 @@ crate fn record_extern_fqn(cx: &DocContext<'_>, did: DefId, kind: clean::TypeKin
     }
 }
 
-crate fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
+crate fn build_external_trait(cx: &mut DocContext<'_>, did: DefId) -> clean::Trait {
     let trait_items =
         cx.tcx.associated_items(did).in_definition_order().map(|item| item.clean(cx)).collect();
 
@@ -207,14 +207,14 @@ crate fn build_external_trait(cx: &DocContext<'_>, did: DefId) -> clean::Trait {
     }
 }
 
-fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
+fn build_external_function(cx: &mut DocContext<'_>, did: DefId) -> clean::Function {
     let sig = cx.tcx.fn_sig(did);
 
     let constness =
         if is_min_const_fn(cx.tcx, did) { hir::Constness::Const } else { hir::Constness::NotConst };
     let asyncness = cx.tcx.asyncness(did);
     let predicates = cx.tcx.predicates_of(did);
-    let (generics, decl) = clean::enter_impl_trait(cx, || {
+    let (generics, decl) = clean::enter_impl_trait(cx, |cx| {
         ((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx))
     });
     clean::Function {
@@ -224,7 +224,7 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
     }
 }
 
-fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum {
+fn build_enum(cx: &mut DocContext<'_>, did: DefId) -> clean::Enum {
     let predicates = cx.tcx.explicit_predicates_of(did);
 
     clean::Enum {
@@ -234,7 +234,7 @@ fn build_enum(cx: &DocContext<'_>, did: DefId) -> clean::Enum {
     }
 }
 
-fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct {
+fn build_struct(cx: &mut DocContext<'_>, did: DefId) -> clean::Struct {
     let predicates = cx.tcx.explicit_predicates_of(did);
     let variant = cx.tcx.adt_def(did).non_enum_variant();
 
@@ -246,7 +246,7 @@ fn build_struct(cx: &DocContext<'_>, did: DefId) -> clean::Struct {
     }
 }
 
-fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
+fn build_union(cx: &mut DocContext<'_>, did: DefId) -> clean::Union {
     let predicates = cx.tcx.explicit_predicates_of(did);
     let variant = cx.tcx.adt_def(did).non_enum_variant();
 
@@ -257,7 +257,7 @@ fn build_union(cx: &DocContext<'_>, did: DefId) -> clean::Union {
     }
 }
 
-fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {
+fn build_type_alias(cx: &mut DocContext<'_>, did: DefId) -> clean::Typedef {
     let predicates = cx.tcx.explicit_predicates_of(did);
     let type_ = cx.tcx.type_of(did).clean(cx);
 
@@ -270,7 +270,7 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef {
 
 /// Builds all inherent implementations of an ADT (struct/union/enum) or Trait item/path/reexport.
 crate fn build_impls(
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
     parent_module: Option<DefId>,
     did: DefId,
     attrs: Option<Attrs<'_>>,
@@ -286,7 +286,7 @@ crate fn build_impls(
 
 /// `parent_module` refers to the parent of the re-export, not the original item
 fn merge_attrs(
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
     parent_module: Option<DefId>,
     old_attrs: Attrs<'_>,
     new_attrs: Option<Attrs<'_>>,
@@ -311,7 +311,7 @@ fn merge_attrs(
 
 /// Builds a specific implementation of a type. The `did` could be a type method or trait method.
 crate fn build_impl(
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
     parent_module: impl Into<Option<DefId>>,
     did: DefId,
     attrs: Option<Attrs<'_>>,
@@ -394,7 +394,7 @@ crate fn build_impl(
                     }
                 })
                 .collect::<Vec<_>>(),
-            clean::enter_impl_trait(cx, || (tcx.generics_of(did), predicates).clean(cx)),
+            clean::enter_impl_trait(cx, |cx| (tcx.generics_of(did), predicates).clean(cx)),
         ),
     };
     let polarity = tcx.impl_polarity(did);
@@ -437,7 +437,11 @@ crate fn build_impl(
     ret.push(item);
 }
 
-fn build_module(cx: &DocContext<'_>, did: DefId, visited: &mut FxHashSet<DefId>) -> clean::Module {
+fn build_module(
+    cx: &mut DocContext<'_>,
+    did: DefId,
+    visited: &mut FxHashSet<DefId>,
+) -> clean::Module {
     let mut items = Vec::new();
 
     // If we're re-exporting a re-export it may actually re-export something in
@@ -495,7 +499,7 @@ crate fn print_inlined_const(cx: &DocContext<'_>, did: DefId) -> String {
     }
 }
 
-fn build_const(cx: &DocContext<'_>, did: DefId) -> clean::Constant {
+fn build_const(cx: &mut DocContext<'_>, did: DefId) -> clean::Constant {
     clean::Constant {
         type_: cx.tcx.type_of(did).clean(cx),
         expr: print_inlined_const(cx, did),
@@ -506,7 +510,7 @@ fn build_const(cx: &DocContext<'_>, did: DefId) -> clean::Constant {
     }
 }
 
-fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {
+fn build_static(cx: &mut DocContext<'_>, did: DefId, mutable: bool) -> clean::Static {
     clean::Static {
         type_: cx.tcx.type_of(did).clean(cx),
         mutability: if mutable { Mutability::Mut } else { Mutability::Not },
@@ -514,7 +518,7 @@ fn build_static(cx: &DocContext<'_>, did: DefId, mutable: bool) -> clean::Static
     }
 }
 
-fn build_macro(cx: &DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind {
+fn build_macro(cx: &mut DocContext<'_>, did: DefId, name: Symbol) -> clean::ItemKind {
     let imported_from = cx.tcx.original_crate_name(did.krate);
     match cx.enter_resolver(|r| r.cstore().load_macro_untracked(did, cx.sess())) {
         LoadedMacro::MacroDef(def, _) => {
@@ -603,7 +607,7 @@ fn separate_supertrait_bounds(
     (g, ty_bounds)
 }
 
-crate fn record_extern_trait(cx: &DocContext<'_>, did: DefId) {
+crate fn record_extern_trait(cx: &mut DocContext<'_>, did: DefId) {
     if did.is_local() {
         return;
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 1b3d3b52cdbdf..1cfa6090ef48d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -49,43 +49,44 @@ crate use self::types::Visibility::{Inherited, Public};
 crate use self::types::*;
 
 crate trait Clean<T> {
-    fn clean(&self, cx: &DocContext<'_>) -> T;
+    fn clean(&self, cx: &mut DocContext<'_>) -> T;
 }
 
 impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
-    fn clean(&self, cx: &DocContext<'_>) -> Vec<U> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Vec<U> {
         self.iter().map(|x| x.clean(cx)).collect()
     }
 }
 
 impl<T: Clean<U>, U, V: Idx> Clean<IndexVec<V, U>> for IndexVec<V, T> {
-    fn clean(&self, cx: &DocContext<'_>) -> IndexVec<V, U> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> IndexVec<V, U> {
         self.iter().map(|x| x.clean(cx)).collect()
     }
 }
 
 impl<T: Clean<U>, U> Clean<U> for &T {
-    fn clean(&self, cx: &DocContext<'_>) -> U {
+    fn clean(&self, cx: &mut DocContext<'_>) -> U {
         (**self).clean(cx)
     }
 }
 
 impl<T: Clean<U>, U> Clean<U> for Rc<T> {
-    fn clean(&self, cx: &DocContext<'_>) -> U {
+    fn clean(&self, cx: &mut DocContext<'_>) -> U {
         (**self).clean(cx)
     }
 }
 
 impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
-    fn clean(&self, cx: &DocContext<'_>) -> Option<U> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Option<U> {
         self.as_ref().map(|v| v.clean(cx))
     }
 }
 
 impl Clean<ExternalCrate> for CrateNum {
-    fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate {
+    fn clean(&self, cx: &mut DocContext<'_>) -> ExternalCrate {
+        let tcx = cx.tcx;
         let root = DefId { krate: *self, index: CRATE_DEF_INDEX };
-        let krate_span = cx.tcx.def_span(root);
+        let krate_span = tcx.def_span(root);
         let krate_src = cx.sess().source_map().span_to_filename(krate_span);
 
         // Collect all inner modules which are tagged as implementations of
@@ -105,7 +106,7 @@ impl Clean<ExternalCrate> for CrateNum {
         // Also note that this does not attempt to deal with modules tagged
         // duplicately for the same primitive. This is handled later on when
         // rendering by delegating everything to a hash map.
-        let as_primitive = |res: Res| {
+        let mut as_primitive = |res: Res| {
             if let Res::Def(DefKind::Mod, def_id) = res {
                 let attrs = cx.tcx.get_attrs(def_id).clean(cx);
                 let mut prim = None;
@@ -125,15 +126,14 @@ impl Clean<ExternalCrate> for CrateNum {
             None
         };
         let primitives = if root.is_local() {
-            cx.tcx
-                .hir()
+            tcx.hir()
                 .krate()
                 .item
                 .module
                 .item_ids
                 .iter()
                 .filter_map(|&id| {
-                    let item = cx.tcx.hir().item(id);
+                    let item = tcx.hir().item(id);
                     match item.kind {
                         hir::ItemKind::Mod(_) => {
                             as_primitive(Res::Def(DefKind::Mod, id.def_id.to_def_id()))
@@ -151,17 +151,12 @@ impl Clean<ExternalCrate> for CrateNum {
                 })
                 .collect()
         } else {
-            cx.tcx
-                .item_children(root)
-                .iter()
-                .map(|item| item.res)
-                .filter_map(as_primitive)
-                .collect()
+            tcx.item_children(root).iter().map(|item| item.res).filter_map(as_primitive).collect()
         };
 
-        let as_keyword = |res: Res| {
+        let mut as_keyword = |res: Res| {
             if let Res::Def(DefKind::Mod, def_id) = res {
-                let attrs = cx.tcx.get_attrs(def_id).clean(cx);
+                let attrs = tcx.get_attrs(def_id).clean(cx);
                 let mut keyword = None;
                 for attr in attrs.lists(sym::doc) {
                     if attr.has_name(sym::keyword) {
@@ -176,15 +171,14 @@ impl Clean<ExternalCrate> for CrateNum {
             None
         };
         let keywords = if root.is_local() {
-            cx.tcx
-                .hir()
+            tcx.hir()
                 .krate()
                 .item
                 .module
                 .item_ids
                 .iter()
                 .filter_map(|&id| {
-                    let item = cx.tcx.hir().item(id);
+                    let item = tcx.hir().item(id);
                     match item.kind {
                         hir::ItemKind::Mod(_) => {
                             as_keyword(Res::Def(DefKind::Mod, id.def_id.to_def_id()))
@@ -199,13 +193,13 @@ impl Clean<ExternalCrate> for CrateNum {
                 })
                 .collect()
         } else {
-            cx.tcx.item_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect()
+            tcx.item_children(root).iter().map(|item| item.res).filter_map(as_keyword).collect()
         };
 
         ExternalCrate {
-            name: cx.tcx.crate_name(*self),
+            name: tcx.crate_name(*self),
             src: krate_src,
-            attrs: cx.tcx.get_attrs(root).clean(cx),
+            attrs: tcx.get_attrs(root).clean(cx),
             primitives,
             keywords,
         }
@@ -213,7 +207,7 @@ impl Clean<ExternalCrate> for CrateNum {
 }
 
 impl Clean<Item> for doctree::Module<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let mut items: Vec<Item> = vec![];
         items.extend(self.foreigns.iter().map(|x| x.clean(cx)));
         items.extend(self.mods.iter().map(|x| x.clean(cx)));
@@ -246,13 +240,13 @@ impl Clean<Item> for doctree::Module<'_> {
 }
 
 impl Clean<Attributes> for [ast::Attribute] {
-    fn clean(&self, cx: &DocContext<'_>) -> Attributes {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Attributes {
         Attributes::from_ast(cx.sess().diagnostic(), self, None)
     }
 }
 
 impl Clean<GenericBound> for hir::GenericBound<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
+    fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
         match *self {
             hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)),
             hir::GenericBound::LangItemTrait(lang_item, span, _, generic_args) => {
@@ -279,7 +273,7 @@ impl Clean<GenericBound> for hir::GenericBound<'_> {
 }
 
 impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
-    fn clean(&self, cx: &DocContext<'_>) -> Type {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         let (trait_ref, bounds) = *self;
         inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait);
         let path = external_path(
@@ -298,7 +292,7 @@ impl Clean<Type> for (ty::TraitRef<'_>, &[TypeBinding]) {
 }
 
 impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
-    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
+    fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
         GenericBound::TraitBound(
             PolyTrait { trait_: (*self, &[][..]).clean(cx), generic_params: vec![] },
             hir::TraitBoundModifier::None,
@@ -307,7 +301,7 @@ impl<'tcx> Clean<GenericBound> for ty::TraitRef<'tcx> {
 }
 
 impl Clean<GenericBound> for (ty::PolyTraitRef<'_>, &[TypeBinding]) {
-    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
+    fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
         let (poly_trait_ref, bounds) = *self;
         let poly_trait_ref = poly_trait_ref.lift_to_tcx(cx.tcx).unwrap();
 
@@ -335,13 +329,13 @@ impl Clean<GenericBound> for (ty::PolyTraitRef<'_>, &[TypeBinding]) {
 }
 
 impl<'tcx> Clean<GenericBound> for ty::PolyTraitRef<'tcx> {
-    fn clean(&self, cx: &DocContext<'_>) -> GenericBound {
+    fn clean(&self, cx: &mut DocContext<'_>) -> GenericBound {
         (*self, &[][..]).clean(cx)
     }
 }
 
 impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
-    fn clean(&self, cx: &DocContext<'_>) -> Option<Vec<GenericBound>> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Option<Vec<GenericBound>> {
         let mut v = Vec::new();
         v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives));
         v.extend(self.types().map(|t| {
@@ -355,7 +349,7 @@ impl<'tcx> Clean<Option<Vec<GenericBound>>> for InternalSubsts<'tcx> {
 }
 
 impl Clean<Lifetime> for hir::Lifetime {
-    fn clean(&self, cx: &DocContext<'_>) -> Lifetime {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Lifetime {
         let def = cx.tcx.named_region(self.hir_id);
         match def {
             Some(
@@ -374,7 +368,7 @@ impl Clean<Lifetime> for hir::Lifetime {
 }
 
 impl Clean<Lifetime> for hir::GenericParam<'_> {
-    fn clean(&self, _: &DocContext<'_>) -> Lifetime {
+    fn clean(&self, _: &mut DocContext<'_>) -> Lifetime {
         match self.kind {
             hir::GenericParamKind::Lifetime { .. } => {
                 if !self.bounds.is_empty() {
@@ -398,7 +392,7 @@ impl Clean<Lifetime> for hir::GenericParam<'_> {
 }
 
 impl Clean<Constant> for hir::ConstArg {
-    fn clean(&self, cx: &DocContext<'_>) -> Constant {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Constant {
         Constant {
             type_: cx
                 .tcx
@@ -412,13 +406,13 @@ impl Clean<Constant> for hir::ConstArg {
 }
 
 impl Clean<Lifetime> for ty::GenericParamDef {
-    fn clean(&self, _cx: &DocContext<'_>) -> Lifetime {
+    fn clean(&self, _cx: &mut DocContext<'_>) -> Lifetime {
         Lifetime(self.name)
     }
 }
 
 impl Clean<Option<Lifetime>> for ty::RegionKind {
-    fn clean(&self, _cx: &DocContext<'_>) -> Option<Lifetime> {
+    fn clean(&self, _cx: &mut DocContext<'_>) -> Option<Lifetime> {
         match *self {
             ty::ReStatic => Some(Lifetime::statik()),
             ty::ReLateBound(_, ty::BoundRegion { kind: ty::BrNamed(_, name) }) => {
@@ -440,7 +434,7 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
 }
 
 impl Clean<WherePredicate> for hir::WherePredicate<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
+    fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate {
         match *self {
             hir::WherePredicate::BoundPredicate(ref wbp) => WherePredicate::BoundPredicate {
                 ty: wbp.bounded_ty.clean(cx),
@@ -460,7 +454,7 @@ impl Clean<WherePredicate> for hir::WherePredicate<'_> {
 }
 
 impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
-    fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> {
         let bound_predicate = self.kind();
         match bound_predicate.skip_binder() {
             ty::PredicateKind::Trait(pred, _) => Some(bound_predicate.rebind(pred).clean(cx)),
@@ -480,7 +474,7 @@ impl<'a> Clean<Option<WherePredicate>> for ty::Predicate<'a> {
 }
 
 impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
-    fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
+    fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate {
         let poly_trait_ref = self.map_bound(|pred| pred.trait_ref);
         WherePredicate::BoundPredicate {
             ty: poly_trait_ref.skip_binder().self_ty().clean(cx),
@@ -492,7 +486,7 @@ impl<'a> Clean<WherePredicate> for ty::PolyTraitPredicate<'a> {
 impl<'tcx> Clean<Option<WherePredicate>>
     for ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>>
 {
-    fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> {
         let ty::OutlivesPredicate(a, b) = self;
 
         if let (ty::ReEmpty(_), ty::ReEmpty(_)) = (a, b) {
@@ -507,7 +501,7 @@ impl<'tcx> Clean<Option<WherePredicate>>
 }
 
 impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>> {
-    fn clean(&self, cx: &DocContext<'_>) -> Option<WherePredicate> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Option<WherePredicate> {
         let ty::OutlivesPredicate(ty, lt) = self;
 
         if let ty::ReEmpty(_) = lt {
@@ -522,14 +516,14 @@ impl<'tcx> Clean<Option<WherePredicate>> for ty::OutlivesPredicate<Ty<'tcx>, ty:
 }
 
 impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
-    fn clean(&self, cx: &DocContext<'_>) -> WherePredicate {
+    fn clean(&self, cx: &mut DocContext<'_>) -> WherePredicate {
         let ty::ProjectionPredicate { projection_ty, ty } = self;
         WherePredicate::EqPredicate { lhs: projection_ty.clean(cx), rhs: ty.clean(cx) }
     }
 }
 
 impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
-    fn clean(&self, cx: &DocContext<'_>) -> Type {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         let lifted = self.lift_to_tcx(cx.tcx).unwrap();
         let trait_ = match lifted.trait_ref(cx.tcx).clean(cx) {
             GenericBound::TraitBound(t, _) => t.trait_,
@@ -544,7 +538,7 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
 }
 
 impl Clean<GenericParamDef> for ty::GenericParamDef {
-    fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
+    fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef {
         let (name, kind) = match self.kind {
             ty::GenericParamDefKind::Lifetime => (self.name, GenericParamDefKind::Lifetime),
             ty::GenericParamDefKind::Type { has_default, synthetic, .. } => {
@@ -574,7 +568,7 @@ impl Clean<GenericParamDef> for ty::GenericParamDef {
 }
 
 impl Clean<GenericParamDef> for hir::GenericParam<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef {
+    fn clean(&self, cx: &mut DocContext<'_>) -> GenericParamDef {
         let (name, kind) = match self.kind {
             hir::GenericParamKind::Lifetime { .. } => {
                 let name = if !self.bounds.is_empty() {
@@ -617,7 +611,7 @@ impl Clean<GenericParamDef> for hir::GenericParam<'_> {
 }
 
 impl Clean<Generics> for hir::Generics<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Generics {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Generics {
         // Synthetic type-parameters are inserted after normal ones.
         // In order for normal parameters to be able to refer to synthetic ones,
         // scans them first.
@@ -697,7 +691,7 @@ impl Clean<Generics> for hir::Generics<'_> {
 }
 
 impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx>) {
-    fn clean(&self, cx: &DocContext<'_>) -> Generics {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Generics {
         use self::WherePredicate as WP;
         use std::collections::BTreeMap;
 
@@ -801,7 +795,8 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, ty::GenericPredicates<'tcx
             if let crate::core::ImplTraitParam::ParamIndex(idx) = param {
                 if let Some(proj) = impl_trait_proj.remove(&idx) {
                     for (trait_did, name, rhs) in proj {
-                        simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs.clean(cx));
+                        let rhs = rhs.clean(cx);
+                        simplify::merge_bounds(cx, &mut bounds, trait_did, name, &rhs);
                     }
                 }
             } else {
@@ -866,7 +861,7 @@ fn clean_fn_or_proc_macro(
     generics: &'a hir::Generics<'a>,
     body_id: hir::BodyId,
     name: &mut Symbol,
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
 ) -> ItemKind {
     let macro_kind = item.attrs.iter().find_map(|a| {
         if a.has_name(sym::proc_macro) {
@@ -921,15 +916,15 @@ fn clean_fn_or_proc_macro(
 }
 
 impl<'a> Clean<Function> for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::BodyId) {
-    fn clean(&self, cx: &DocContext<'_>) -> Function {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Function {
         let (generics, decl) =
-            enter_impl_trait(cx, || (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)));
+            enter_impl_trait(cx, |cx| (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)));
         Function { decl, generics, header: self.0.header }
     }
 }
 
 impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], &'a [Ident]) {
-    fn clean(&self, cx: &DocContext<'_>) -> Arguments {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Arguments {
         Arguments {
             values: self
                 .0
@@ -948,7 +943,7 @@ impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], &'a [Ident]) {
 }
 
 impl<'a> Clean<Arguments> for (&'a [hir::Ty<'a>], hir::BodyId) {
-    fn clean(&self, cx: &DocContext<'_>) -> Arguments {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Arguments {
         let body = cx.tcx.hir().body(self.1);
 
         Arguments {
@@ -969,7 +964,7 @@ impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl<'a>, A)
 where
     (&'a [hir::Ty<'a>], A): Clean<Arguments>,
 {
-    fn clean(&self, cx: &DocContext<'_>) -> FnDecl {
+    fn clean(&self, cx: &mut DocContext<'_>) -> FnDecl {
         FnDecl {
             inputs: (self.0.inputs, self.1).clean(cx),
             output: self.0.output.clean(cx),
@@ -980,7 +975,7 @@ where
 }
 
 impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
-    fn clean(&self, cx: &DocContext<'_>) -> FnDecl {
+    fn clean(&self, cx: &mut DocContext<'_>) -> FnDecl {
         let (did, sig) = *self;
         let mut names = if did.is_local() { &[] } else { cx.tcx.fn_arg_names(did) }.iter();
 
@@ -1004,7 +999,7 @@ impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
 }
 
 impl Clean<FnRetTy> for hir::FnRetTy<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> FnRetTy {
+    fn clean(&self, cx: &mut DocContext<'_>) -> FnRetTy {
         match *self {
             Self::Return(ref typ) => Return(typ.clean(cx)),
             Self::DefaultReturn(..) => DefaultReturn,
@@ -1013,7 +1008,7 @@ impl Clean<FnRetTy> for hir::FnRetTy<'_> {
 }
 
 impl Clean<bool> for hir::IsAuto {
-    fn clean(&self, _: &DocContext<'_>) -> bool {
+    fn clean(&self, _: &mut DocContext<'_>) -> bool {
         match *self {
             hir::IsAuto::Yes => true,
             hir::IsAuto::No => false,
@@ -1022,13 +1017,14 @@ impl Clean<bool> for hir::IsAuto {
 }
 
 impl Clean<Type> for hir::TraitRef<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Type {
-        resolve_type(cx, self.path.clean(cx), self.hir_ref_id)
+    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
+        let path = self.path.clean(cx);
+        resolve_type(cx, path, self.hir_ref_id)
     }
 }
 
 impl Clean<PolyTrait> for hir::PolyTraitRef<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> PolyTrait {
+    fn clean(&self, cx: &mut DocContext<'_>) -> PolyTrait {
         PolyTrait {
             trait_: self.trait_ref.clean(cx),
             generic_params: self.bound_generic_params.clean(cx),
@@ -1037,15 +1033,15 @@ impl Clean<PolyTrait> for hir::PolyTraitRef<'_> {
 }
 
 impl Clean<TypeKind> for hir::def::DefKind {
-    fn clean(&self, _: &DocContext<'_>) -> TypeKind {
+    fn clean(&self, _: &mut DocContext<'_>) -> TypeKind {
         (*self).into()
     }
 }
 
 impl Clean<Item> for hir::TraitItem<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let local_did = self.def_id.to_def_id();
-        cx.with_param_env(local_did, || {
+        cx.with_param_env(local_did, |cx| {
             let inner = match self.kind {
                 hir::TraitItemKind::Const(ref ty, default) => {
                     AssocConstItem(ty.clean(cx), default.map(|e| print_const_expr(cx.tcx, e)))
@@ -1060,7 +1056,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
                     MethodItem(m, None)
                 }
                 hir::TraitItemKind::Fn(ref sig, hir::TraitFn::Required(ref names)) => {
-                    let (generics, decl) = enter_impl_trait(cx, || {
+                    let (generics, decl) = enter_impl_trait(cx, |cx| {
                         (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
                     });
                     let mut t = Function { header: sig.header, decl, generics };
@@ -1084,9 +1080,9 @@ impl Clean<Item> for hir::TraitItem<'_> {
 }
 
 impl Clean<Item> for hir::ImplItem<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let local_did = self.def_id.to_def_id();
-        cx.with_param_env(local_did, || {
+        cx.with_param_env(local_did, |cx| {
             let inner = match self.kind {
                 hir::ImplItemKind::Const(ref ty, expr) => {
                     AssocConstItem(ty.clean(cx), Some(print_const_expr(cx.tcx, expr)))
@@ -1133,10 +1129,11 @@ impl Clean<Item> for hir::ImplItem<'_> {
 }
 
 impl Clean<Item> for ty::AssocItem {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
+        let tcx = cx.tcx;
         let kind = match self.kind {
             ty::AssocKind::Const => {
-                let ty = cx.tcx.type_of(self.def_id);
+                let ty = tcx.type_of(self.def_id);
                 let default = if self.defaultness.has_value() {
                     Some(inline::print_inlined_const(cx, self.def_id))
                 } else {
@@ -1146,15 +1143,15 @@ impl Clean<Item> for ty::AssocItem {
             }
             ty::AssocKind::Fn => {
                 let generics =
-                    (cx.tcx.generics_of(self.def_id), cx.tcx.explicit_predicates_of(self.def_id))
+                    (tcx.generics_of(self.def_id), tcx.explicit_predicates_of(self.def_id))
                         .clean(cx);
-                let sig = cx.tcx.fn_sig(self.def_id);
+                let sig = tcx.fn_sig(self.def_id);
                 let mut decl = (self.def_id, sig).clean(cx);
 
                 if self.fn_has_self_parameter {
                     let self_ty = match self.container {
-                        ty::ImplContainer(def_id) => cx.tcx.type_of(def_id),
-                        ty::TraitContainer(_) => cx.tcx.types.self_param,
+                        ty::ImplContainer(def_id) => tcx.type_of(def_id),
+                        ty::TraitContainer(_) => tcx.types.self_param,
                     };
                     let self_arg_ty = sig.input(0).skip_binder();
                     if self_arg_ty == self_ty {
@@ -1176,12 +1173,12 @@ impl Clean<Item> for ty::AssocItem {
                     ty::TraitContainer(_) => self.defaultness.has_value(),
                 };
                 if provided {
-                    let constness = if is_min_const_fn(cx.tcx, self.def_id) {
+                    let constness = if is_min_const_fn(tcx, self.def_id) {
                         hir::Constness::Const
                     } else {
                         hir::Constness::NotConst
                     };
-                    let asyncness = cx.tcx.asyncness(self.def_id);
+                    let asyncness = tcx.asyncness(self.def_id);
                     let defaultness = match self.container {
                         ty::ImplContainer(_) => Some(self.defaultness),
                         ty::TraitContainer(_) => None,
@@ -1216,9 +1213,9 @@ impl Clean<Item> for ty::AssocItem {
                 let my_name = self.ident.name;
 
                 if let ty::TraitContainer(_) = self.container {
-                    let bounds = cx.tcx.explicit_item_bounds(self.def_id);
+                    let bounds = tcx.explicit_item_bounds(self.def_id);
                     let predicates = ty::GenericPredicates { parent: None, predicates: bounds };
-                    let generics = (cx.tcx.generics_of(self.def_id), predicates).clean(cx);
+                    let generics = (tcx.generics_of(self.def_id), predicates).clean(cx);
                     let mut bounds = generics
                         .where_predicates
                         .iter()
@@ -1258,7 +1255,7 @@ impl Clean<Item> for ty::AssocItem {
                     }
 
                     let ty = if self.defaultness.has_value() {
-                        Some(cx.tcx.type_of(self.def_id))
+                        Some(tcx.type_of(self.def_id))
                     } else {
                         None
                     };
@@ -1266,7 +1263,7 @@ impl Clean<Item> for ty::AssocItem {
                     AssocTypeItem(bounds, ty.clean(cx))
                 } else {
                     // FIXME: when could this happen? Associated items in inherent impls?
-                    let type_ = cx.tcx.type_of(self.def_id).clean(cx);
+                    let type_ = tcx.type_of(self.def_id).clean(cx);
                     TypedefItem(
                         Typedef {
                             type_,
@@ -1283,7 +1280,7 @@ impl Clean<Item> for ty::AssocItem {
     }
 }
 
-fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type {
+fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &mut DocContext<'_>) -> Type {
     use rustc_hir::GenericParamCount;
     let hir::Ty { hir_id, span, ref kind } = *hir_ty;
     let qpath = match kind {
@@ -1389,9 +1386,10 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type {
                         }
                     }
                 }
-                return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx));
+                return cx.enter_alias(ty_substs, lt_substs, ct_substs, |cx| ty.clean(cx));
             }
-            resolve_type(cx, path.clean(cx), hir_id)
+            let path = path.clean(cx);
+            resolve_type(cx, path, hir_id)
         }
         hir::QPath::Resolved(Some(ref qself), ref p) => {
             // Try to normalize `<X as Y>::T` to a type
@@ -1423,11 +1421,11 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type {
             } else {
                 Res::Err
             };
-            let trait_path = hir::Path { span, res, segments: &[] };
+            let trait_path = hir::Path { span, res, segments: &[] }.clean(cx);
             Type::QPath {
                 name: segment.ident.name,
                 self_type: box qself.clean(cx),
-                trait_: box resolve_type(cx, trait_path.clean(cx), hir_id),
+                trait_: box resolve_type(cx, trait_path, hir_id),
             }
         }
         hir::QPath::LangItem(..) => bug!("clean: requiring documentation of lang item"),
@@ -1435,7 +1433,7 @@ fn clean_qpath(hir_ty: &hir::Ty<'_>, cx: &DocContext<'_>) -> Type {
 }
 
 impl Clean<Type> for hir::Ty<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Type {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         use rustc_hir::*;
 
         match self.kind {
@@ -1507,7 +1505,7 @@ impl Clean<Type> for hir::Ty<'_> {
 }
 
 /// Returns `None` if the type could not be normalized
-fn normalize(cx: &DocContext<'tcx>, ty: Ty<'_>) -> Option<Ty<'tcx>> {
+fn normalize(cx: &mut DocContext<'tcx>, ty: Ty<'_>) -> Option<Ty<'tcx>> {
     // HACK: low-churn fix for #79459 while we wait for a trait normalization fix
     if !cx.tcx.sess.opts.debugging_opts.normalize_docs {
         return None;
@@ -1538,7 +1536,7 @@ fn normalize(cx: &DocContext<'tcx>, ty: Ty<'_>) -> Option<Ty<'tcx>> {
 }
 
 impl<'tcx> Clean<Type> for Ty<'tcx> {
-    fn clean(&self, cx: &DocContext<'_>) -> Type {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Type {
         debug!("cleaning type: {:?}", self);
         let ty = normalize(cx, self).unwrap_or(self);
         match *ty.kind() {
@@ -1746,7 +1744,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
 }
 
 impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
-    fn clean(&self, cx: &DocContext<'_>) -> Constant {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Constant {
         Constant {
             type_: self.ty.clean(cx),
             expr: format!("{}", self),
@@ -1757,7 +1755,7 @@ impl<'tcx> Clean<Constant> for ty::Const<'tcx> {
 }
 
 impl Clean<Item> for hir::StructField<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let what_rustc_thinks = Item::from_hir_id_and_parts(
             self.hir_id,
             Some(self.ident.name),
@@ -1770,7 +1768,7 @@ impl Clean<Item> for hir::StructField<'_> {
 }
 
 impl Clean<Item> for ty::FieldDef {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let what_rustc_thinks = Item::from_def_id_and_parts(
             self.did,
             Some(self.ident.name),
@@ -1783,7 +1781,7 @@ impl Clean<Item> for ty::FieldDef {
 }
 
 impl Clean<Visibility> for hir::Visibility<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Visibility {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Visibility {
         match self.node {
             hir::VisibilityKind::Public => Visibility::Public,
             hir::VisibilityKind::Inherited => Visibility::Inherited,
@@ -1801,7 +1799,7 @@ impl Clean<Visibility> for hir::Visibility<'_> {
 }
 
 impl Clean<Visibility> for ty::Visibility {
-    fn clean(&self, _cx: &DocContext<'_>) -> Visibility {
+    fn clean(&self, _cx: &mut DocContext<'_>) -> Visibility {
         match *self {
             ty::Visibility::Public => Visibility::Public,
             // NOTE: this is not quite right: `ty` uses `Invisible` to mean 'private',
@@ -1816,7 +1814,7 @@ impl Clean<Visibility> for ty::Visibility {
 }
 
 impl Clean<VariantStruct> for rustc_hir::VariantData<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> VariantStruct {
+    fn clean(&self, cx: &mut DocContext<'_>) -> VariantStruct {
         VariantStruct {
             struct_type: CtorKind::from_hir(self),
             fields: self.fields().iter().map(|x| x.clean(cx)).collect(),
@@ -1826,7 +1824,7 @@ impl Clean<VariantStruct> for rustc_hir::VariantData<'_> {
 }
 
 impl Clean<Item> for ty::VariantDef {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let kind = match self.ctor_kind {
             CtorKind::Const => Variant::CLike,
             CtorKind::Fn => Variant::Tuple(
@@ -1857,7 +1855,7 @@ impl Clean<Item> for ty::VariantDef {
 }
 
 impl Clean<Variant> for hir::VariantData<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Variant {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Variant {
         match self {
             hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)),
             hir::VariantData::Tuple(..) => {
@@ -1869,13 +1867,13 @@ impl Clean<Variant> for hir::VariantData<'_> {
 }
 
 impl Clean<Span> for rustc_span::Span {
-    fn clean(&self, _cx: &DocContext<'_>) -> Span {
+    fn clean(&self, _cx: &mut DocContext<'_>) -> Span {
         Span::from_rustc_span(*self)
     }
 }
 
 impl Clean<Path> for hir::Path<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Path {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Path {
         Path {
             global: self.is_global(),
             res: self.res,
@@ -1885,7 +1883,7 @@ impl Clean<Path> for hir::Path<'_> {
 }
 
 impl Clean<GenericArgs> for hir::GenericArgs<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> GenericArgs {
+    fn clean(&self, cx: &mut DocContext<'_>) -> GenericArgs {
         if self.parenthesized {
             let output = self.bindings[0].ty().clean(cx);
             GenericArgs::Parenthesized {
@@ -1913,28 +1911,28 @@ impl Clean<GenericArgs> for hir::GenericArgs<'_> {
 }
 
 impl Clean<PathSegment> for hir::PathSegment<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> PathSegment {
+    fn clean(&self, cx: &mut DocContext<'_>) -> PathSegment {
         PathSegment { name: self.ident.name, args: self.args().clean(cx) }
     }
 }
 
 impl Clean<String> for Ident {
     #[inline]
-    fn clean(&self, cx: &DocContext<'_>) -> String {
+    fn clean(&self, cx: &mut DocContext<'_>) -> String {
         self.name.clean(cx)
     }
 }
 
 impl Clean<String> for Symbol {
     #[inline]
-    fn clean(&self, _: &DocContext<'_>) -> String {
+    fn clean(&self, _: &mut DocContext<'_>) -> String {
         self.to_string()
     }
 }
 
 impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl {
-        let (generic_params, decl) = enter_impl_trait(cx, || {
+    fn clean(&self, cx: &mut DocContext<'_>) -> BareFunctionDecl {
+        let (generic_params, decl) = enter_impl_trait(cx, |cx| {
             (self.generic_params.clean(cx), (&*self.decl, self.param_names).clean(cx))
         });
         BareFunctionDecl { unsafety: self.unsafety, abi: self.abi, decl, generic_params }
@@ -1942,13 +1940,13 @@ impl Clean<BareFunctionDecl> for hir::BareFnTy<'_> {
 }
 
 impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
-    fn clean(&self, cx: &DocContext<'_>) -> Vec<Item> {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Vec<Item> {
         use hir::ItemKind;
 
         let (item, renamed) = self;
         let def_id = item.def_id.to_def_id();
         let mut name = renamed.unwrap_or_else(|| cx.tcx.hir().name(item.hir_id()));
-        cx.with_param_env(def_id, || {
+        cx.with_param_env(def_id, |cx| {
             let kind = match item.kind {
                 ItemKind::Static(ty, mutability, body_id) => {
                     StaticItem(Static { type_: ty.clean(cx), mutability, expr: Some(body_id) })
@@ -2031,7 +2029,7 @@ impl Clean<Vec<Item>> for (&hir::Item<'_>, Option<Symbol>) {
 }
 
 impl Clean<Item> for hir::Variant<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let kind = VariantItem(self.data.clean(cx));
         let what_rustc_thinks =
             Item::from_hir_id_and_parts(self.id, Some(self.ident.name), kind, cx);
@@ -2042,7 +2040,7 @@ impl Clean<Item> for hir::Variant<'_> {
 
 impl Clean<bool> for ty::ImplPolarity {
     /// Returns whether the impl has negative polarity.
-    fn clean(&self, _: &DocContext<'_>) -> bool {
+    fn clean(&self, _: &mut DocContext<'_>) -> bool {
         match self {
             &ty::ImplPolarity::Positive |
             // FIXME: do we want to do something else here?
@@ -2052,30 +2050,31 @@ impl Clean<bool> for ty::ImplPolarity {
     }
 }
 
-fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &DocContext<'_>) -> Vec<Item> {
+fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &mut DocContext<'_>) -> Vec<Item> {
+    let tcx = cx.tcx;
     let mut ret = Vec::new();
     let trait_ = impl_.of_trait.clean(cx);
     let items =
-        impl_.items.iter().map(|ii| cx.tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>();
-    let def_id = cx.tcx.hir().local_def_id(hir_id);
+        impl_.items.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::<Vec<_>>();
+    let def_id = tcx.hir().local_def_id(hir_id);
 
     // If this impl block is an implementation of the Deref trait, then we
     // need to try inlining the target's inherent impl blocks as well.
-    if trait_.def_id() == cx.tcx.lang_items().deref_trait() {
+    if trait_.def_id() == tcx.lang_items().deref_trait() {
         build_deref_target_impls(cx, &items, &mut ret);
     }
 
     let provided: FxHashSet<Symbol> = trait_
         .def_id()
-        .map(|did| cx.tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
+        .map(|did| tcx.provided_trait_methods(did).map(|meth| meth.ident.name).collect())
         .unwrap_or_default();
 
     let for_ = impl_.self_ty.clean(cx);
-    let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) {
-        DefKind::TyAlias => Some(cx.tcx.type_of(did).clean(cx)),
+    let type_alias = for_.def_id().and_then(|did| match tcx.def_kind(did) {
+        DefKind::TyAlias => Some(tcx.type_of(did).clean(cx)),
         _ => None,
     });
-    let make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| {
+    let mut make_item = |trait_: Option<Type>, for_: Type, items: Vec<Item>| {
         let kind = ImplItem(Impl {
             unsafety: impl_.unsafety,
             generics: impl_.generics.clean(cx),
@@ -2083,7 +2082,7 @@ fn clean_impl(impl_: &hir::Impl<'_>, hir_id: hir::HirId, cx: &DocContext<'_>) ->
             trait_,
             for_,
             items,
-            negative_polarity: cx.tcx.impl_polarity(def_id).clean(cx),
+            negative_polarity: tcx.impl_polarity(def_id).clean(cx),
             synthetic: false,
             blanket_impl: None,
         });
@@ -2100,7 +2099,7 @@ fn clean_extern_crate(
     krate: &hir::Item<'_>,
     name: Symbol,
     orig_name: Option<Symbol>,
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
 ) -> Vec<Item> {
     // this is the ID of the `extern crate` statement
     let cnum = cx.tcx.extern_mod_stmt_cnum(krate.def_id).unwrap_or(LOCAL_CRATE);
@@ -2147,7 +2146,7 @@ fn clean_use_statement(
     name: Symbol,
     path: &hir::Path<'_>,
     kind: hir::UseKind,
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
 ) -> Vec<Item> {
     // We need this comparison because some imports (for std types for example)
     // are "inserted" as well but directly by the compiler and they should not be
@@ -2237,13 +2236,13 @@ fn clean_use_statement(
 }
 
 impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let (item, renamed) = self;
-        cx.with_param_env(item.def_id.to_def_id(), || {
+        cx.with_param_env(item.def_id.to_def_id(), |cx| {
             let kind = match item.kind {
                 hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => {
                     let abi = cx.tcx.hir().get_foreign_abi(item.hir_id());
-                    let (generics, decl) = enter_impl_trait(cx, || {
+                    let (generics, decl) = enter_impl_trait(cx, |cx| {
                         (generics.clean(cx), (&**decl, &names[..]).clean(cx))
                     });
                     ForeignFunctionItem(Function {
@@ -2274,7 +2273,7 @@ impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
 }
 
 impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
-    fn clean(&self, cx: &DocContext<'_>) -> Item {
+    fn clean(&self, cx: &mut DocContext<'_>) -> Item {
         let (item, renamed) = self;
         let name = renamed.unwrap_or(item.ident.name);
         let tts = item.ast.body.inner_tokens().trees().collect::<Vec<_>>();
@@ -2323,13 +2322,13 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
 }
 
 impl Clean<TypeBinding> for hir::TypeBinding<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> TypeBinding {
+    fn clean(&self, cx: &mut DocContext<'_>) -> TypeBinding {
         TypeBinding { name: self.ident.name, kind: self.kind.clean(cx) }
     }
 }
 
 impl Clean<TypeBindingKind> for hir::TypeBindingKind<'_> {
-    fn clean(&self, cx: &DocContext<'_>) -> TypeBindingKind {
+    fn clean(&self, cx: &mut DocContext<'_>) -> TypeBindingKind {
         match *self {
             hir::TypeBindingKind::Equality { ref ty } => {
                 TypeBindingKind::Equality { ty: ty.clean(cx) }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index e1ccbfd9da9de..3e7196fa7fa03 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -130,7 +130,7 @@ impl Item {
         hir_id: hir::HirId,
         name: Option<Symbol>,
         kind: ItemKind,
-        cx: &DocContext<'_>,
+        cx: &mut DocContext<'_>,
     ) -> Item {
         Item::from_def_id_and_parts(cx.tcx.hir().local_def_id(hir_id).to_def_id(), name, kind, cx)
     }
@@ -139,7 +139,7 @@ impl Item {
         def_id: DefId,
         name: Option<Symbol>,
         kind: ItemKind,
-        cx: &DocContext<'_>,
+        cx: &mut DocContext<'_>,
     ) -> Item {
         debug!("name={:?}, def_id={:?}", name, def_id);
 
@@ -936,7 +936,7 @@ crate enum GenericBound {
 }
 
 impl GenericBound {
-    crate fn maybe_sized(cx: &DocContext<'_>) -> GenericBound {
+    crate fn maybe_sized(cx: &mut DocContext<'_>) -> GenericBound {
         let did = cx.tcx.require_lang_item(LangItem::Sized, None);
         let empty = cx.tcx.intern_substs(&[]);
         let path = external_path(cx, cx.tcx.item_name(did), Some(did), false, vec![], empty);
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 59af49b0d8a28..c7bfd363a129b 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -90,7 +90,7 @@ crate fn krate(mut cx: &mut DocContext<'_>) -> Crate {
 }
 
 fn external_generic_args(
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
     trait_did: Option<DefId>,
     has_self: bool,
     bindings: Vec<TypeBinding>,
@@ -142,7 +142,7 @@ fn external_generic_args(
 // trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
 // from Fn<(A, B,), C> to Fn(A, B) -> C
 pub(super) fn external_path(
-    cx: &DocContext<'_>,
+    cx: &mut DocContext<'_>,
     name: Symbol,
     trait_did: Option<DefId>,
     has_self: bool,
@@ -214,7 +214,7 @@ crate fn qpath_to_string(p: &hir::QPath<'_>) -> String {
     s
 }
 
-crate fn build_deref_target_impls(cx: &DocContext<'_>, items: &[Item], ret: &mut Vec<Item>) {
+crate fn build_deref_target_impls(cx: &mut DocContext<'_>, items: &[Item], ret: &mut Vec<Item>) {
     let tcx = cx.tcx;
 
     for item in items {
@@ -241,7 +241,7 @@ crate trait ToSource {
 
 impl ToSource for rustc_span::Span {
     fn to_src(&self, cx: &DocContext<'_>) -> String {
-        debug!("converting span {:?} to snippet", self.clean(cx));
+        debug!("converting span {:?} to snippet", self);
         let sn = match cx.sess().source_map().span_to_snippet(*self) {
             Ok(x) => x,
             Err(_) => String::new(),
@@ -407,7 +407,7 @@ crate fn print_const_expr(tcx: TyCtxt<'_>, body: hir::BodyId) -> String {
 }
 
 /// Given a type Path, resolve it to a Type using the TyCtxt
-crate fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type {
+crate fn resolve_type(cx: &mut DocContext<'_>, path: Path, id: hir::HirId) -> Type {
     debug!("resolve_type({:?},{:?})", path, id);
 
     let is_generic = match path.res {
@@ -421,12 +421,12 @@ crate fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type {
         Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true,
         _ => false,
     };
-    let did = register_res(&*cx, path.res);
+    let did = register_res(cx, path.res);
     ResolvedPath { path, param_names: None, did, is_generic }
 }
 
 crate fn get_auto_trait_and_blanket_impls(
-    cx: &DocContext<'tcx>,
+    cx: &mut DocContext<'tcx>,
     ty: Ty<'tcx>,
     param_env_def_id: DefId,
 ) -> impl Iterator<Item = Item> {
@@ -439,11 +439,11 @@ crate fn get_auto_trait_and_blanket_impls(
         .sess()
         .prof
         .generic_activity("get_blanket_impls")
-        .run(|| BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id));
+        .run(|| BlanketImplFinder { cx }.get_blanket_impls(ty, param_env_def_id));
     auto_impls.into_iter().chain(blanket_impls)
 }
 
-crate fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
+crate fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
     debug!("register_res({:?})", res);
 
     let (did, kind) = match res {
@@ -483,21 +483,21 @@ crate fn register_res(cx: &DocContext<'_>, res: Res) -> DefId {
     did
 }
 
-crate fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource {
+crate fn resolve_use_source(cx: &mut DocContext<'_>, path: Path) -> ImportSource {
     ImportSource {
         did: if path.res.opt_def_id().is_none() { None } else { Some(register_res(cx, path.res)) },
         path,
     }
 }
 
-crate fn enter_impl_trait<F, R>(cx: &DocContext<'_>, f: F) -> R
+crate fn enter_impl_trait<F, R>(cx: &mut DocContext<'_>, f: F) -> R
 where
-    F: FnOnce() -> R,
+    F: FnOnce(&mut DocContext<'_>) -> R,
 {
-    let old_bounds = mem::take(&mut *cx.impl_trait_bounds.borrow_mut());
-    let r = f();
+    let old_bounds = mem::take(&mut *cx.impl_trait_bounds.get_mut());
+    let r = f(cx);
     assert!(cx.impl_trait_bounds.borrow().is_empty());
-    *cx.impl_trait_bounds.borrow_mut() = old_bounds;
+    *cx.impl_trait_bounds.get_mut() = old_bounds;
     r
 }
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index d79c47bbe3de6..71daea3d714be 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -83,13 +83,13 @@ crate struct DocContext<'tcx> {
 }
 
 impl<'tcx> DocContext<'tcx> {
-    crate fn sess(&self) -> &Session {
+    crate fn sess(&self) -> &'tcx Session {
         &self.tcx.sess
     }
 
-    crate fn with_param_env<T, F: FnOnce() -> T>(&self, def_id: DefId, f: F) -> T {
+    crate fn with_param_env<T, F: FnOnce(&mut Self) -> T>(&mut self, def_id: DefId, f: F) -> T {
         let old_param_env = self.param_env.replace(self.tcx.param_env(def_id));
-        let ret = f();
+        let ret = f(self);
         self.param_env.set(old_param_env);
         ret
     }
@@ -104,24 +104,24 @@ impl<'tcx> DocContext<'tcx> {
     /// Call the closure with the given parameters set as
     /// the substitutions for a type alias' RHS.
     crate fn enter_alias<F, R>(
-        &self,
+        &mut self,
         ty_substs: FxHashMap<DefId, clean::Type>,
         lt_substs: FxHashMap<DefId, clean::Lifetime>,
         ct_substs: FxHashMap<DefId, clean::Constant>,
         f: F,
     ) -> R
     where
-        F: FnOnce() -> R,
+        F: FnOnce(&mut Self) -> R,
     {
         let (old_tys, old_lts, old_cts) = (
-            mem::replace(&mut *self.ty_substs.borrow_mut(), ty_substs),
-            mem::replace(&mut *self.lt_substs.borrow_mut(), lt_substs),
-            mem::replace(&mut *self.ct_substs.borrow_mut(), ct_substs),
+            mem::replace(&mut *self.ty_substs.get_mut(), ty_substs),
+            mem::replace(&mut *self.lt_substs.get_mut(), lt_substs),
+            mem::replace(&mut *self.ct_substs.get_mut(), ct_substs),
         );
-        let r = f();
-        *self.ty_substs.borrow_mut() = old_tys;
-        *self.lt_substs.borrow_mut() = old_lts;
-        *self.ct_substs.borrow_mut() = old_cts;
+        let r = f(self);
+        *self.ty_substs.get_mut() = old_tys;
+        *self.lt_substs.get_mut() = old_lts;
+        *self.ct_substs.get_mut() = old_cts;
         r
     }
 
@@ -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));
         }
     }
 
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 914ad35e7a488..f5eb92c1bb5aa 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -181,7 +181,7 @@ impl<'tcx> Context<'tcx> {
         self.shared.tcx
     }
 
-    fn sess(&self) -> &Session {
+    fn sess(&self) -> &'tcx Session {
         &self.shared.tcx.sess
     }
 }
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index bbb833e54aeb9..689cda76cc094 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -70,8 +70,8 @@ impl DocFolder for SourceCollector<'_, '_> {
     }
 }
 
-impl SourceCollector<'_, '_> {
-    fn sess(&self) -> &Session {
+impl SourceCollector<'_, 'tcx> {
+    fn sess(&self) -> &'tcx Session {
         &self.scx.tcx.sess
     }
 
diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs
index b31276c9dcb7f..ce88e09b174e5 100644
--- a/src/librustdoc/json/mod.rs
+++ b/src/librustdoc/json/mod.rs
@@ -37,8 +37,8 @@ crate struct JsonRenderer<'tcx> {
     cache: Rc<Cache>,
 }
 
-impl JsonRenderer<'_> {
-    fn sess(&self) -> &Session {
+impl JsonRenderer<'tcx> {
+    fn sess(&self) -> &'tcx Session {
         self.tcx.sess
     }
 
diff --git a/src/librustdoc/passes/calculate_doc_coverage.rs b/src/librustdoc/passes/calculate_doc_coverage.rs
index cdbff62d0645c..542cf6d2c275a 100644
--- a/src/librustdoc/passes/calculate_doc_coverage.rs
+++ b/src/librustdoc/passes/calculate_doc_coverage.rs
@@ -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
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 9516130034b59..c85490864ec70 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -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)
 }
 
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index a54b4adc13295..2c2ae9d03bf82 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -47,8 +47,14 @@ 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 +263,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 +279,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 +290,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 +314,8 @@ 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 +324,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,20 +377,14 @@ 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
-                    .associated_items(impl_)
-                    .find_by_name_and_namespace(
-                        cx.tcx,
-                        Ident::with_dummy_span(item_name),
-                        ns,
-                        impl_,
-                    )
+                tcx.associated_items(impl_)
+                    .find_by_name_and_namespace(tcx, Ident::with_dummy_span(item_name), ns, impl_)
                     .map(|item| {
                         let kind = item.kind;
                         self.kind_side_channel.set(Some((kind.as_def_kind(), item.def_id)));
@@ -434,9 +425,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 +488,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 +938,18 @@ 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 +1101,7 @@ impl LinkCollector<'_, '_> {
                 if matches!(disambiguator, Some(Disambiguator::Primitive)) {
                     if fragment.is_some() {
                         anchor_failure(
-                            cx,
+                            self.cx,
                             &item,
                             path_str,
                             dox,
@@ -1119,7 +1115,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 +1136,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 +1183,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 +1207,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 +1239,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 })
             }
         }
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 0951a9c2c9794..0b6d81d1b447e 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -14,9 +14,11 @@ 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);
-    let mut krate = cx.sess().time("collect_synthetic_impls", || synth.fold_crate(krate));
+crate fn collect_trait_impls(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
+    let (mut krate, synth_impls) = cx.sess().time("collect_synthetic_impls", || {
+        let mut synth = SyntheticImplCollector { cx, impls: Vec::new() };
+        (synth.fold_crate(krate), synth.impls)
+    });
 
     let prims: FxHashSet<PrimitiveType> = krate.primitives.iter().map(|p| p.1).collect();
 
@@ -142,7 +144,7 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
         panic!("collect-trait-impls can't run");
     };
 
-    items.extend(synth.impls);
+    items.extend(synth_impls);
     for it in new_items.drain(..) {
         if let ImplItem(Impl { ref for_, ref trait_, ref blanket_impl, .. }) = *it.kind {
             if !(cleaner.keep_impl(for_)
@@ -160,16 +162,10 @@ crate fn collect_trait_impls(krate: Crate, cx: &DocContext<'_>) -> Crate {
 }
 
 struct SyntheticImplCollector<'a, 'tcx> {
-    cx: &'a DocContext<'tcx>,
+    cx: &'a mut DocContext<'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() {
diff --git a/src/librustdoc/passes/doc_test_lints.rs b/src/librustdoc/passes/doc_test_lints.rs
index 11f572560d606..042a895d2fa2f 100644
--- a/src/librustdoc/passes/doc_test_lints.rs
+++ b/src/librustdoc/passes/doc_test_lints.rs
@@ -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))
     }
diff --git a/src/librustdoc/passes/html_tags.rs b/src/librustdoc/passes/html_tags.rs
index 38ec2bef0adeb..a6fe7e228d7e8 100644
--- a/src/librustdoc/passes/html_tags.rs
+++ b/src/librustdoc/passes/html_tags.rs
@@ -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)
     }
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 7ac42c7599248..5813732facb6e 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -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,
 }
 
diff --git a/src/librustdoc/passes/non_autolinks.rs b/src/librustdoc/passes/non_autolinks.rs
index efb5df08cafdb..9d4539a9769ca 100644
--- a/src/librustdoc/passes/non_autolinks.rs
+++ b/src/librustdoc/passes/non_autolinks.rs
@@ -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,12 @@ 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)
     }
diff --git a/src/librustdoc/passes/propagate_doc_cfg.rs b/src/librustdoc/passes/propagate_doc_cfg.rs
index 6722d7c2fc9fe..2369ff78b1ce0 100644
--- a/src/librustdoc/passes/propagate_doc_cfg.rs
+++ b/src/librustdoc/passes/propagate_doc_cfg.rs
@@ -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)
 }
 
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index 79f8562c4726d..c742d32cb62ea 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -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
diff --git a/src/librustdoc/passes/strip_priv_imports.rs b/src/librustdoc/passes/strip_priv_imports.rs
index 6eeaabacbc138..63869324cb8d2 100644
--- a/src/librustdoc/passes/strip_priv_imports.rs
+++ b/src/librustdoc/passes/strip_priv_imports.rs
@@ -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)
 }
diff --git a/src/librustdoc/passes/strip_private.rs b/src/librustdoc/passes/strip_private.rs
index e812bcd87fe3c..c0bb05af3edb5 100644
--- a/src/librustdoc/passes/strip_private.rs
+++ b/src/librustdoc/passes/strip_private.rs
@@ -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();
diff --git a/src/librustdoc/passes/unindent_comments.rs b/src/librustdoc/passes/unindent_comments.rs
index 1cad480d4e847..da2eda7364122 100644
--- a/src/librustdoc/passes/unindent_comments.rs
+++ b/src/librustdoc/passes/unindent_comments.rs
@@ -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)
 }