about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2021-01-28 16:07:24 +0100
committerGuillaume Gomez <guillaume1.gomez@gmail.com>2021-02-05 17:23:52 +0100
commit4810910b0b2be1f28a2ed666ad1a3825b00bb933 (patch)
tree959a84a05d7fe79a66680d2c7f3797b662daa70c /src
parentd5174a4b0d3a72c8edefd65b2c1108f3168b24e0 (diff)
downloadrust-4810910b0b2be1f28a2ed666ad1a3825b00bb933.tar.gz
rust-4810910b0b2be1f28a2ed666ad1a3825b00bb933.zip
Remove Function all_types and ret_types fields
Diffstat (limited to 'src')
-rw-r--r--src/librustdoc/clean/inline.rs3
-rw-r--r--src/librustdoc/clean/mod.rs31
-rw-r--r--src/librustdoc/clean/types.rs2
-rw-r--r--src/librustdoc/clean/utils.rs126
-rw-r--r--src/librustdoc/formats/cache.rs105
-rw-r--r--src/librustdoc/formats/renderer.rs1
-rw-r--r--src/librustdoc/html/render/cache.rs32
-rw-r--r--src/librustdoc/html/render/mod.rs2
-rw-r--r--src/librustdoc/json/conversions.rs4
9 files changed, 88 insertions, 218 deletions
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 2588c00f2cf..cdff37cbd51 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -217,13 +217,10 @@ fn build_external_function(cx: &DocContext<'_>, did: DefId) -> clean::Function {
     let (generics, decl) = clean::enter_impl_trait(cx, || {
         ((cx.tcx.generics_of(did), predicates).clean(cx), (did, sig).clean(cx))
     });
-    let (all_types, ret_types) = clean::get_all_types(&generics, &decl, cx);
     clean::Function {
         decl,
         generics,
         header: hir::FnHeader { unsafety: sig.unsafety(), abi: sig.abi(), constness, asyncness },
-        all_types,
-        ret_types,
     }
 }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 03454bb8b7f..0815d779708 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -928,8 +928,7 @@ impl<'a> Clean<Function> for (&'a hir::FnSig<'a>, &'a hir::Generics<'a>, hir::Bo
     fn clean(&self, cx: &DocContext<'_>) -> Function {
         let (generics, decl) =
             enter_impl_trait(cx, || (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)));
-        let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
-        Function { decl, generics, header: self.0.header, all_types, ret_types }
+        Function { decl, generics, header: self.0.header }
     }
 }
 
@@ -1043,21 +1042,7 @@ impl Clean<PolyTrait> for hir::PolyTraitRef<'_> {
 
 impl Clean<TypeKind> for hir::def::DefKind {
     fn clean(&self, _: &DocContext<'_>) -> TypeKind {
-        match *self {
-            hir::def::DefKind::Mod => TypeKind::Module,
-            hir::def::DefKind::Struct => TypeKind::Struct,
-            hir::def::DefKind::Union => TypeKind::Union,
-            hir::def::DefKind::Enum => TypeKind::Enum,
-            hir::def::DefKind::Trait => TypeKind::Trait,
-            hir::def::DefKind::TyAlias => TypeKind::Typedef,
-            hir::def::DefKind::ForeignTy => TypeKind::Foreign,
-            hir::def::DefKind::TraitAlias => TypeKind::TraitAlias,
-            hir::def::DefKind::Fn => TypeKind::Function,
-            hir::def::DefKind::Const => TypeKind::Const,
-            hir::def::DefKind::Static => TypeKind::Static,
-            hir::def::DefKind::Macro(_) => TypeKind::Macro,
-            _ => TypeKind::Foreign,
-        }
+        self.into()
     }
 }
 
@@ -1082,9 +1067,7 @@ impl Clean<Item> for hir::TraitItem<'_> {
                     let (generics, decl) = enter_impl_trait(cx, || {
                         (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx))
                     });
-                    let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
-                    let mut t =
-                        Function { header: sig.header, decl, generics, all_types, ret_types };
+                    let mut t = Function { header: sig.header, decl, generics };
                     if t.header.constness == hir::Constness::Const
                         && is_unstable_const_fn(cx.tcx, local_did).is_some()
                     {
@@ -1196,7 +1179,6 @@ impl Clean<Item> for ty::AssocItem {
                     ty::ImplContainer(_) => true,
                     ty::TraitContainer(_) => self.defaultness.has_value(),
                 };
-                let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
                 if provided {
                     let constness = if is_min_const_fn(cx.tcx, self.def_id) {
                         hir::Constness::Const
@@ -1218,8 +1200,6 @@ impl Clean<Item> for ty::AssocItem {
                                 constness,
                                 asyncness,
                             },
-                            all_types,
-                            ret_types,
                         },
                         defaultness,
                     )
@@ -1233,8 +1213,6 @@ impl Clean<Item> for ty::AssocItem {
                             constness: hir::Constness::NotConst,
                             asyncness: hir::IsAsync::NotAsync,
                         },
-                        all_types,
-                        ret_types,
                     })
                 }
             }
@@ -2274,7 +2252,6 @@ impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
                     let (generics, decl) = enter_impl_trait(cx, || {
                         (generics.clean(cx), (&**decl, &names[..]).clean(cx))
                     });
-                    let (all_types, ret_types) = get_all_types(&generics, &decl, cx);
                     ForeignFunctionItem(Function {
                         decl,
                         generics,
@@ -2284,8 +2261,6 @@ impl Clean<Item> for (&hir::ForeignItem<'_>, Option<Symbol>) {
                             constness: hir::Constness::NotConst,
                             asyncness: hir::IsAsync::NotAsync,
                         },
-                        all_types,
-                        ret_types,
                     })
                 }
                 hir::ForeignItemKind::Static(ref ty, mutability) => ForeignStaticItem(Static {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index cbe871bd65a..efa7fcc6838 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1087,8 +1087,6 @@ crate struct Function {
     crate decl: FnDecl,
     crate generics: Generics,
     crate header: hir::FnHeader,
-    crate all_types: Vec<(Type, TypeKind)>,
-    crate ret_types: Vec<(Type, TypeKind)>,
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index e380d4672d0..2c829c49953 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -1,10 +1,9 @@
 use crate::clean::auto_trait::AutoTraitFinder;
 use crate::clean::blanket_impl::BlanketImplFinder;
 use crate::clean::{
-    inline, Clean, Crate, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg, GenericArgs,
-    GenericBound, Generics, GetDefId, ImportSource, Item, ItemKind, Lifetime, MacroKind, Path,
-    PathSegment, Primitive, PrimitiveType, ResolvedPath, Type, TypeBinding, TypeKind,
-    WherePredicate,
+    inline, Clean, Crate, ExternalCrate, Generic, GenericArg, GenericArgs, ImportSource, Item,
+    ItemKind, Lifetime, MacroKind, Path, PathSegment, Primitive, PrimitiveType, ResolvedPath, Type,
+    TypeBinding, TypeKind,
 };
 use crate::core::DocContext;
 
@@ -160,125 +159,6 @@ pub(super) fn external_path(
     }
 }
 
-/// The point of this function is to replace bounds with types.
-///
-/// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option<T>` will return
-/// `[Display, Option]` (we just returns the list of the types, we don't care about the
-/// wrapped types in here).
-crate fn get_real_types(
-    generics: &Generics,
-    arg: &Type,
-    cx: &DocContext<'_>,
-    recurse: i32,
-) -> FxHashSet<(Type, TypeKind)> {
-    fn insert(res: &mut FxHashSet<(Type, TypeKind)>, cx: &DocContext<'_>, ty: Type) {
-        if let Some(kind) = ty.def_id().map(|did| cx.tcx.def_kind(did).clean(cx)) {
-            res.insert((ty, kind));
-        } else if ty.is_primitive() {
-            // This is a primitive, let's store it as such.
-            res.insert((ty, TypeKind::Primitive));
-        }
-    }
-    let mut res = FxHashSet::default();
-    if recurse >= 10 {
-        // FIXME: remove this whole recurse thing when the recursion bug is fixed
-        return res;
-    }
-
-    if arg.is_full_generic() {
-        let arg_s = Symbol::intern(&arg.print(&cx.cache).to_string());
-        if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g {
-            WherePredicate::BoundPredicate { ty, .. } => ty.def_id() == arg.def_id(),
-            _ => false,
-        }) {
-            let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);
-            for bound in bounds.iter() {
-                if let GenericBound::TraitBound(poly_trait, _) = bound {
-                    for x in poly_trait.generic_params.iter() {
-                        if !x.is_type() {
-                            continue;
-                        }
-                        if let Some(ty) = x.get_type() {
-                            let adds = get_real_types(generics, &ty, cx, recurse + 1);
-                            if !adds.is_empty() {
-                                res.extend(adds);
-                            } else if !ty.is_full_generic() {
-                                insert(&mut res, cx, ty);
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
-            for bound in bound.get_bounds().unwrap_or_else(|| &[]) {
-                if let Some(ty) = bound.get_trait_type() {
-                    let adds = get_real_types(generics, &ty, cx, recurse + 1);
-                    if !adds.is_empty() {
-                        res.extend(adds);
-                    } else if !ty.is_full_generic() {
-                        insert(&mut res, cx, ty);
-                    }
-                }
-            }
-        }
-    } else {
-        insert(&mut res, cx, arg.clone());
-        if let Some(gens) = arg.generics() {
-            for gen in gens.iter() {
-                if gen.is_full_generic() {
-                    let adds = get_real_types(generics, gen, cx, recurse + 1);
-                    if !adds.is_empty() {
-                        res.extend(adds);
-                    }
-                } else {
-                    insert(&mut res, cx, gen.clone());
-                }
-            }
-        }
-    }
-    res
-}
-
-/// Return the full list of types when bounds have been resolved.
-///
-/// i.e. `fn foo<A: Display, B: Option<A>>(x: u32, y: B)` will return
-/// `[u32, Display, Option]`.
-crate fn get_all_types(
-    generics: &Generics,
-    decl: &FnDecl,
-    cx: &DocContext<'_>,
-) -> (Vec<(Type, TypeKind)>, Vec<(Type, TypeKind)>) {
-    let mut all_types = FxHashSet::default();
-    for arg in decl.inputs.values.iter() {
-        if arg.type_.is_self_type() {
-            continue;
-        }
-        let args = get_real_types(generics, &arg.type_, cx, 0);
-        if !args.is_empty() {
-            all_types.extend(args);
-        } else {
-            if let Some(kind) = arg.type_.def_id().map(|did| cx.tcx.def_kind(did).clean(cx)) {
-                all_types.insert((arg.type_.clone(), kind));
-            }
-        }
-    }
-
-    let ret_types = match decl.output {
-        FnRetTy::Return(ref return_type) => {
-            let mut ret = get_real_types(generics, &return_type, cx, 0);
-            if ret.is_empty() {
-                if let Some(kind) = return_type.def_id().map(|did| cx.tcx.def_kind(did).clean(cx)) {
-                    ret.insert((return_type.clone(), kind));
-                }
-            }
-            ret.into_iter().collect()
-        }
-        _ => Vec::new(),
-    };
-    (all_types.into_iter().collect(), ret_types)
-}
-
 crate fn strip_type(ty: Type) -> Type {
     match ty {
         Type::ResolvedPath { path, param_names, did, is_generic } => {
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index c506f5a37b1..ce1204c7be1 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -5,6 +5,7 @@ use std::path::{Path, PathBuf};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
 use rustc_middle::middle::privacy::AccessLevels;
+use rustc_middle::ty::TyCtxt;
 use rustc_span::source_map::FileName;
 use rustc_span::Symbol;
 
@@ -121,13 +122,21 @@ crate struct Cache {
     crate aliases: BTreeMap<String, Vec<usize>>,
 }
 
+/// This struct is used to wrap the `cache` and `tcx` in order to run `DocFolder`.
+struct CacheBuilder<'a, 'tcx> {
+    cache: &'a mut Cache,
+    empty_cache: Cache,
+    tcx: TyCtxt<'tcx>,
+}
+
 impl Cache {
-    crate fn from_krate(
+    crate fn from_krate<'tcx>(
         render_info: RenderInfo,
         document_private: bool,
         extern_html_root_urls: &BTreeMap<String, String>,
         dst: &Path,
         mut krate: clean::Crate,
+        tcx: TyCtxt<'tcx>,
     ) -> (clean::Crate, Cache) {
         // Crawl the crate to build various caches used for the output
         let RenderInfo {
@@ -194,7 +203,8 @@ impl Cache {
 
         cache.stack.push(krate.name.to_string());
 
-        krate = cache.fold_crate(krate);
+        krate = CacheBuilder { tcx, cache: &mut cache, empty_cache: Cache::default() }
+            .fold_crate(krate);
 
         for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) {
             if cache.traits.contains_key(&trait_did) {
@@ -208,7 +218,7 @@ impl Cache {
     }
 }
 
-impl DocFolder for Cache {
+impl<'a, 'tcx> DocFolder for CacheBuilder<'a, 'tcx> {
     fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
         if item.def_id.is_local() {
             debug!("folding {} \"{:?}\", id {:?}", item.type_(), item.name, item.def_id);
@@ -218,17 +228,17 @@ impl DocFolder for Cache {
         // we don't want it or its children in the search index.
         let orig_stripped_mod = match *item.kind {
             clean::StrippedItem(box clean::ModuleItem(..)) => {
-                mem::replace(&mut self.stripped_mod, true)
+                mem::replace(&mut self.cache.stripped_mod, true)
             }
-            _ => self.stripped_mod,
+            _ => self.cache.stripped_mod,
         };
 
         // If the impl is from a masked crate or references something from a
         // masked crate then remove it completely.
         if let clean::ImplItem(ref i) = *item.kind {
-            if self.masked_crates.contains(&item.def_id.krate)
-                || i.trait_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate))
-                || i.for_.def_id().map_or(false, |d| self.masked_crates.contains(&d.krate))
+            if self.cache.masked_crates.contains(&item.def_id.krate)
+                || i.trait_.def_id().map_or(false, |d| self.cache.masked_crates.contains(&d.krate))
+                || i.for_.def_id().map_or(false, |d| self.cache.masked_crates.contains(&d.krate))
             {
                 return None;
             }
@@ -237,14 +247,15 @@ impl DocFolder for Cache {
         // Propagate a trait method's documentation to all implementors of the
         // trait.
         if let clean::TraitItem(ref t) = *item.kind {
-            self.traits.entry(item.def_id).or_insert_with(|| t.clone());
+            self.cache.traits.entry(item.def_id).or_insert_with(|| t.clone());
         }
 
         // Collect all the implementors of traits.
         if let clean::ImplItem(ref i) = *item.kind {
             if let Some(did) = i.trait_.def_id() {
                 if i.blanket_impl.is_none() {
-                    self.implementors
+                    self.cache
+                        .implementors
                         .entry(did)
                         .or_default()
                         .push(Impl { impl_item: item.clone() });
@@ -257,7 +268,7 @@ impl DocFolder for Cache {
             let (parent, is_inherent_impl_item) = match *item.kind {
                 clean::StrippedItem(..) => ((None, None), false),
                 clean::AssocConstItem(..) | clean::TypedefItem(_, true)
-                    if self.parent_is_trait_impl =>
+                    if self.cache.parent_is_trait_impl =>
                 {
                     // skip associated items in trait impls
                     ((None, None), false)
@@ -267,18 +278,18 @@ impl DocFolder for Cache {
                 | clean::StructFieldItem(..)
                 | clean::VariantItem(..) => (
                     (
-                        Some(*self.parent_stack.last().expect("parent_stack is empty")),
-                        Some(&self.stack[..self.stack.len() - 1]),
+                        Some(*self.cache.parent_stack.last().expect("parent_stack is empty")),
+                        Some(&self.cache.stack[..self.cache.stack.len() - 1]),
                     ),
                     false,
                 ),
                 clean::MethodItem(..) | clean::AssocConstItem(..) => {
-                    if self.parent_stack.is_empty() {
+                    if self.cache.parent_stack.is_empty() {
                         ((None, None), false)
                     } else {
-                        let last = self.parent_stack.last().expect("parent_stack is empty 2");
+                        let last = self.cache.parent_stack.last().expect("parent_stack is empty 2");
                         let did = *last;
-                        let path = match self.paths.get(&did) {
+                        let path = match self.cache.paths.get(&did) {
                             // The current stack not necessarily has correlation
                             // for where the type was defined. On the other
                             // hand, `paths` always has the right
@@ -290,24 +301,24 @@ impl DocFolder for Cache {
                                 | ItemType::Union
                                 | ItemType::Enum,
                             )) => Some(&fqp[..fqp.len() - 1]),
-                            Some(..) => Some(&*self.stack),
+                            Some(..) => Some(&*self.cache.stack),
                             None => None,
                         };
                         ((Some(*last), path), true)
                     }
                 }
-                _ => ((None, Some(&*self.stack)), false),
+                _ => ((None, Some(&*self.cache.stack)), false),
             };
 
             match parent {
-                (parent, Some(path)) if is_inherent_impl_item || !self.stripped_mod => {
+                (parent, Some(path)) if is_inherent_impl_item || !self.cache.stripped_mod => {
                     debug_assert!(!item.is_stripped());
 
                     // A crate has a module at its root, containing all items,
                     // which should not be indexed. The crate-item itself is
                     // inserted later on when serializing the search-index.
                     if item.def_id.index != CRATE_DEF_INDEX {
-                        self.search_index.push(IndexItem {
+                        self.cache.search_index.push(IndexItem {
                             ty: item.type_(),
                             name: s.to_string(),
                             path: path.join("::"),
@@ -316,21 +327,22 @@ impl DocFolder for Cache {
                                 .map_or_else(String::new, |x| short_markdown_summary(&x.as_str())),
                             parent,
                             parent_idx: None,
-                            search_type: get_index_search_type(&item, None),
+                            search_type: get_index_search_type(&item, &self.empty_cache, self.tcx),
                         });
 
                         for alias in item.attrs.get_doc_aliases() {
-                            self.aliases
+                            self.cache
+                                .aliases
                                 .entry(alias.to_lowercase())
                                 .or_insert(Vec::new())
-                                .push(self.search_index.len() - 1);
+                                .push(self.cache.search_index.len() - 1);
                         }
                     }
                 }
                 (Some(parent), None) if is_inherent_impl_item => {
                     // We have a parent, but we don't know where they're
                     // defined yet. Wait for later to index this item.
-                    self.orphan_impl_items.push((parent, item.clone()));
+                    self.cache.orphan_impl_items.push((parent, item.clone()));
                 }
                 _ => {}
             }
@@ -339,7 +351,7 @@ impl DocFolder for Cache {
         // Keep track of the fully qualified path for this item.
         let pushed = match item.name {
             Some(n) if !n.is_empty() => {
-                self.stack.push(n.to_string());
+                self.cache.stack.push(n.to_string());
                 true
             }
             _ => false,
@@ -361,7 +373,7 @@ impl DocFolder for Cache {
             | clean::MacroItem(..)
             | clean::ProcMacroItem(..)
             | clean::VariantItem(..)
-                if !self.stripped_mod =>
+                if !self.cache.stripped_mod =>
             {
                 // Re-exported items mean that the same id can show up twice
                 // in the rustdoc ast that we're looking at. We know,
@@ -369,21 +381,21 @@ impl DocFolder for Cache {
                 // `public_items` map, so we can skip inserting into the
                 // paths map if there was already an entry present and we're
                 // not a public item.
-                if !self.paths.contains_key(&item.def_id)
-                    || self.access_levels.is_public(item.def_id)
+                if !self.cache.paths.contains_key(&item.def_id)
+                    || self.cache.access_levels.is_public(item.def_id)
                 {
-                    self.paths.insert(item.def_id, (self.stack.clone(), item.type_()));
+                    self.cache.paths.insert(item.def_id, (self.cache.stack.clone(), item.type_()));
                 }
             }
             clean::PrimitiveItem(..) => {
-                self.paths.insert(item.def_id, (self.stack.clone(), item.type_()));
+                self.cache.paths.insert(item.def_id, (self.cache.stack.clone(), item.type_()));
             }
 
             _ => {}
         }
 
         // Maintain the parent stack
-        let orig_parent_is_trait_impl = self.parent_is_trait_impl;
+        let orig_parent_is_trait_impl = self.cache.parent_is_trait_impl;
         let parent_pushed = match *item.kind {
             clean::TraitItem(..)
             | clean::EnumItem(..)
@@ -391,24 +403,24 @@ impl DocFolder for Cache {
             | clean::StructItem(..)
             | clean::UnionItem(..)
             | clean::VariantItem(..) => {
-                self.parent_stack.push(item.def_id);
-                self.parent_is_trait_impl = false;
+                self.cache.parent_stack.push(item.def_id);
+                self.cache.parent_is_trait_impl = false;
                 true
             }
             clean::ImplItem(ref i) => {
-                self.parent_is_trait_impl = i.trait_.is_some();
+                self.cache.parent_is_trait_impl = i.trait_.is_some();
                 match i.for_ {
                     clean::ResolvedPath { did, .. } => {
-                        self.parent_stack.push(did);
+                        self.cache.parent_stack.push(did);
                         true
                     }
                     ref t => {
                         let prim_did = t
                             .primitive_type()
-                            .and_then(|t| self.primitive_locations.get(&t).cloned());
+                            .and_then(|t| self.cache.primitive_locations.get(&t).cloned());
                         match prim_did {
                             Some(did) => {
-                                self.parent_stack.push(did);
+                                self.cache.parent_stack.push(did);
                                 true
                             }
                             None => false,
@@ -433,8 +445,9 @@ impl DocFolder for Cache {
                     dids.insert(did);
                 }
                 ref t => {
-                    let did =
-                        t.primitive_type().and_then(|t| self.primitive_locations.get(&t).cloned());
+                    let did = t
+                        .primitive_type()
+                        .and_then(|t| self.cache.primitive_locations.get(&t).cloned());
 
                     if let Some(did) = did {
                         dids.insert(did);
@@ -450,13 +463,13 @@ impl DocFolder for Cache {
                 }
             }
             let impl_item = Impl { impl_item: item };
-            if impl_item.trait_did().map_or(true, |d| self.traits.contains_key(&d)) {
+            if impl_item.trait_did().map_or(true, |d| self.cache.traits.contains_key(&d)) {
                 for did in dids {
-                    self.impls.entry(did).or_insert(vec![]).push(impl_item.clone());
+                    self.cache.impls.entry(did).or_insert(vec![]).push(impl_item.clone());
                 }
             } else {
                 let trait_did = impl_item.trait_did().expect("no trait did");
-                self.orphan_trait_impls.push((trait_did, dids, impl_item));
+                self.cache.orphan_trait_impls.push((trait_did, dids, impl_item));
             }
             None
         } else {
@@ -464,13 +477,13 @@ impl DocFolder for Cache {
         };
 
         if pushed {
-            self.stack.pop().expect("stack already empty");
+            self.cache.stack.pop().expect("stack already empty");
         }
         if parent_pushed {
-            self.parent_stack.pop().expect("parent stack already empty");
+            self.cache.parent_stack.pop().expect("parent stack already empty");
         }
-        self.stripped_mod = orig_stripped_mod;
-        self.parent_is_trait_impl = orig_parent_is_trait_impl;
+        self.cache.stripped_mod = orig_stripped_mod;
+        self.cache.parent_is_trait_impl = orig_parent_is_trait_impl;
         ret
     }
 }
diff --git a/src/librustdoc/formats/renderer.rs b/src/librustdoc/formats/renderer.rs
index 6ecc4695dc8..6437ba45511 100644
--- a/src/librustdoc/formats/renderer.rs
+++ b/src/librustdoc/formats/renderer.rs
@@ -61,6 +61,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
             &options.extern_html_root_urls,
             &options.output,
             krate,
+            tcx,
         )
     });
     let prof = &tcx.sess.prof;
diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs
index 4dd7110f331..e47692063bd 100644
--- a/src/librustdoc/html/render/cache.rs
+++ b/src/librustdoc/html/render/cache.rs
@@ -1,11 +1,14 @@
 use std::collections::BTreeMap;
 use std::path::Path;
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::{sym, Symbol};
 use serde::Serialize;
 
-use crate::clean::types::GetDefId;
+use crate::clean::types::{
+    FnDecl, FnRetTy, GenericBound, Generics, GetDefId, Type, TypeKind, WherePredicate,
+};
 use crate::clean::{self, AttributesExt};
 use crate::formats::cache::Cache;
 use crate::formats::item_type::ItemType;
@@ -62,11 +65,13 @@ crate fn extern_location(
 }
 
 /// Builds the search index from the collected metadata
-crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
+crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<'tcx>) -> String {
     let mut defid_to_pathid = FxHashMap::default();
     let mut crate_items = Vec::with_capacity(cache.search_index.len());
     let mut crate_paths = vec![];
 
+    // For now we don't get the primitive types in the search index.
+    let empty_cache = Cache::default();
     // Attach all orphan items to the type's definition if the type
     // has since been learned.
     for &(did, ref item) in &cache.orphan_impl_items {
@@ -78,7 +83,7 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
                 desc: item.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)),
                 parent: Some(did),
                 parent_idx: None,
-                search_type: get_index_search_type(&item, Some(cache)),
+                search_type: get_index_search_type(&item, cache),
             });
             for alias in item.attrs.get_doc_aliases() {
                 cache
@@ -164,14 +169,15 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
     )
 }
 
-crate fn get_index_search_type(
+crate fn get_index_search_type<'tcx>(
     item: &clean::Item,
-    cache: Option<&Cache>,
+    cache: &Cache,
+    tcx: TyCtxt<'tcx>,
 ) -> Option<IndexItemFunctionType> {
     let (all_types, ret_types) = match *item.kind {
-        clean::FunctionItem(ref f) => (&f.all_types, &f.ret_types),
-        clean::MethodItem(ref m, _) => (&m.all_types, &m.ret_types),
-        clean::TyMethodItem(ref m) => (&m.all_types, &m.ret_types),
+        clean::FunctionItem(ref f) => get_all_types(&f.generics, &f.decl, tcx, &cache),
+        clean::MethodItem(ref m, _) => get_all_types(&m.generics, &m.decl, tcx, &cache),
+        clean::TyMethodItem(ref m) => get_all_types(&m.generics, &m.decl, tcx, &cache),
         _ => return None,
     };
 
@@ -190,9 +196,9 @@ crate fn get_index_search_type(
     Some(IndexItemFunctionType { inputs, output })
 }
 
-fn get_index_type(clean_type: &clean::Type, cache: &Option<&Cache>) -> RenderType {
+fn get_index_type(clean_type: &clean::Type, cache: &Cache) -> RenderType {
     RenderType {
-        ty: cache.map_or_else(|| clean_type.def_id(), |cache| clean_type.def_id_full(cache)),
+        ty: clean_type.def_id_full(cache),
         idx: None,
         name: get_index_type_name(clean_type, true).map(|s| s.as_str().to_ascii_lowercase()),
         generics: get_generics(clean_type, cache),
@@ -227,14 +233,14 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
     }
 }
 
-fn get_generics(clean_type: &clean::Type, cache: &Option<&Cache>) -> Option<Vec<Generic>> {
+fn get_generics(clean_type: &clean::Type, cache: &Cache) -> Option<Vec<Generic>> {
     clean_type.generics().and_then(|types| {
         let r = types
             .iter()
             .filter_map(|t| {
                 get_index_type_name(t, false).map(|name| Generic {
                     name: name.as_str().to_ascii_lowercase(),
-                    defid: cache.map_or_else(|| t.def_id(), |cache| t.def_id_full(cache)),
+                    defid: t.def_id_full(cache),
                     idx: None,
                 })
             })
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 6909ab870db..16366d7b131 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -499,7 +499,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         krate = sources::render(&dst, &mut scx, krate)?;
 
         // Build our search index
-        let index = build_index(&krate, &mut cache);
+        let index = build_index(&krate, &mut cache, tcx);
 
         let mut cx = Context {
             current: Vec::new(),
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 026d8f96dee..9107ba59bd0 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -238,7 +238,7 @@ fn stringify_header(header: &rustc_hir::FnHeader) -> String {
 
 impl From<clean::Function> for Function {
     fn from(function: clean::Function) -> Self {
-        let clean::Function { decl, generics, header, all_types: _, ret_types: _ } = function;
+        let clean::Function { decl, generics, header } = function;
         Function {
             decl: decl.into(),
             generics: generics.into(),
@@ -435,7 +435,7 @@ impl From<clean::Impl> for Impl {
 }
 
 crate fn from_function_method(function: clean::Function, has_body: bool) -> Method {
-    let clean::Function { header, decl, generics, all_types: _, ret_types: _ } = function;
+    let clean::Function { header, decl, generics } = function;
     Method {
         decl: decl.into(),
         generics: generics.into(),