@@ -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