@@ -70,8 +70,6 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
7070 let mut crate_items = Vec::with_capacity(cache.search_index.len());
7171 let mut crate_paths = vec![];
7272
73- // For now we don't get the primitive types in the search index.
74- let empty_cache = Cache::default();
7573 // Attach all orphan items to the type's definition if the type
7674 // has since been learned.
7775 for &(did, ref item) in &cache.orphan_impl_items {
@@ -83,7 +81,7 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
8381 desc: item.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)),
8482 parent: Some(did),
8583 parent_idx: None,
86- search_type: get_index_search_type(&item, cache),
84+ search_type: get_index_search_type(&item, cache, tcx ),
8785 });
8886 for alias in item.attrs.get_doc_aliases() {
8987 cache
@@ -248,3 +246,127 @@ fn get_generics(clean_type: &clean::Type, cache: &Cache) -> Option<Vec<Generic>>
248246 if r.is_empty() { None } else { Some(r) }
249247 })
250248}
249+
250+ /// The point of this function is to replace bounds with types.
251+ ///
252+ /// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option<T>` will return
253+ /// `[Display, Option]` (we just returns the list of the types, we don't care about the
254+ /// wrapped types in here).
255+ crate fn get_real_types<'tcx>(
256+ generics: &Generics,
257+ arg: &Type,
258+ tcx: TyCtxt<'tcx>,
259+ recurse: i32,
260+ cache: &Cache,
261+ res: &mut FxHashSet<(Type, TypeKind)>,
262+ ) -> usize {
263+ fn insert(res: &mut FxHashSet<(Type, TypeKind)>, tcx: TyCtxt<'_>, ty: Type) -> usize {
264+ if let Some(kind) = ty.def_id().map(|did| tcx.def_kind(did).into()) {
265+ res.insert((ty, kind));
266+ 1
267+ } else if ty.is_primitive() {
268+ // This is a primitive, let's store it as such.
269+ res.insert((ty, TypeKind::Primitive));
270+ 1
271+ } else {
272+ 0
273+ }
274+ }
275+
276+ if recurse >= 10 {
277+ // FIXME: remove this whole recurse thing when the recursion bug is fixed
278+ return 0;
279+ }
280+ let mut nb_added = 0;
281+
282+ if arg.is_full_generic() {
283+ let arg_s = Symbol::intern(&arg.print(cache).to_string());
284+ if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g {
285+ WherePredicate::BoundPredicate { ty, .. } => ty.def_id() == arg.def_id(),
286+ _ => false,
287+ }) {
288+ let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]);
289+ for bound in bounds.iter() {
290+ if let GenericBound::TraitBound(poly_trait, _) = bound {
291+ for x in poly_trait.generic_params.iter() {
292+ if !x.is_type() {
293+ continue;
294+ }
295+ if let Some(ty) = x.get_type() {
296+ let adds = get_real_types(generics, &ty, tcx, recurse + 1, cache, res);
297+ nb_added += adds;
298+ if adds == 0 && !ty.is_full_generic() {
299+ nb_added += insert(res, tcx, ty);
300+ }
301+ }
302+ }
303+ }
304+ }
305+ }
306+ if let Some(bound) = generics.params.iter().find(|g| g.is_type() && g.name == arg_s) {
307+ for bound in bound.get_bounds().unwrap_or_else(|| &[]) {
308+ if let Some(ty) = bound.get_trait_type() {
309+ let adds = get_real_types(generics, &ty, tcx, recurse + 1, cache, res);
310+ nb_added += adds;
311+ if adds == 0 && !ty.is_full_generic() {
312+ nb_added += insert(res, tcx, ty);
313+ }
314+ }
315+ }
316+ }
317+ } else {
318+ nb_added += insert(res, tcx, arg.clone());
319+ if let Some(gens) = arg.generics() {
320+ for gen in gens.iter() {
321+ if gen.is_full_generic() {
322+ nb_added += get_real_types(generics, gen, tcx, recurse + 1, cache, res);
323+ } else {
324+ nb_added += insert(res, tcx, (*gen).clone());
325+ }
326+ }
327+ }
328+ }
329+ nb_added
330+ }
331+
332+ /// Return the full list of types when bounds have been resolved.
333+ ///
334+ /// i.e. `fn foo<A: Display, B: Option<A>>(x: u32, y: B)` will return
335+ /// `[u32, Display, Option]`.
336+ crate fn get_all_types<'tcx>(
337+ generics: &Generics,
338+ decl: &FnDecl,
339+ tcx: TyCtxt<'tcx>,
340+ cache: &Cache,
341+ ) -> (Vec<(Type, TypeKind)>, Vec<(Type, TypeKind)>) {
342+ let mut all_types = FxHashSet::default();
343+ for arg in decl.inputs.values.iter() {
344+ if arg.type_.is_self_type() {
345+ continue;
346+ }
347+ let mut args = FxHashSet::default();
348+ get_real_types(generics, &arg.type_, tcx, 0, cache, &mut args);
349+ if !args.is_empty() {
350+ all_types.extend(args);
351+ } else {
352+ if let Some(kind) = arg.type_.def_id().map(|did| tcx.def_kind(did).into()) {
353+ all_types.insert((arg.type_.clone(), kind));
354+ }
355+ }
356+ }
357+
358+ let ret_types = match decl.output {
359+ FnRetTy::Return(ref return_type) => {
360+ let mut ret = FxHashSet::default();
361+ get_real_types(generics, &return_type, tcx, 0, cache, &mut ret);
362+ if ret.is_empty() {
363+ if let Some(kind) = return_type.def_id().map(|did| tcx.def_kind(did).into()) {
364+ ret.insert((return_type.clone(), kind));
365+ }
366+ }
367+ ret.into_iter().collect()
368+ }
369+ _ => Vec::new(),
370+ };
371+ (all_types.into_iter().collect(), ret_types)
372+ }
0 commit comments