@@ -70,8 +70,6 @@ crate fn build_index<'tcx>(krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<
70
70
let mut crate_items = Vec :: with_capacity ( cache. search_index . len ( ) ) ;
71
71
let mut crate_paths = vec ! [ ] ;
72
72
73
- // For now we don't get the primitive types in the search index.
74
- let empty_cache = Cache :: default ( ) ;
75
73
// Attach all orphan items to the type's definition if the type
76
74
// has since been learned.
77
75
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<
83
81
desc : item. doc_value ( ) . map_or_else ( String :: new, |s| short_markdown_summary ( & s) ) ,
84
82
parent : Some ( did) ,
85
83
parent_idx : None ,
86
- search_type : get_index_search_type ( & item, cache) ,
84
+ search_type : get_index_search_type ( & item, cache, tcx ) ,
87
85
} ) ;
88
86
for alias in item. attrs . get_doc_aliases ( ) {
89
87
cache
@@ -248,3 +246,127 @@ fn get_generics(clean_type: &clean::Type, cache: &Cache) -> Option<Vec<Generic>>
248
246
if r. is_empty ( ) { None } else { Some ( r) }
249
247
} )
250
248
}
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