@@ -25,7 +25,7 @@ pub(crate) fn build_index<'tcx>(
25
25
26
26
// Attach all orphan items to the type's definition if the type
27
27
// has since been learned.
28
- for & ( did, ref item) in & cache. orphan_impl_items {
28
+ for & ( did, ref item, ref impl_generics , from_blanket_or_auto_impl ) in & cache. orphan_impl_items {
29
29
if let Some ( & ( ref fqp, _) ) = cache. paths . get ( & did) {
30
30
let desc = item
31
31
. doc_value ( )
@@ -37,7 +37,13 @@ pub(crate) fn build_index<'tcx>(
37
37
desc,
38
38
parent : Some ( did) ,
39
39
parent_idx : None ,
40
- search_type : get_function_type_for_search ( item, tcx, cache) ,
40
+ search_type : get_function_type_for_search (
41
+ item,
42
+ tcx,
43
+ impl_generics. as_ref ( ) ,
44
+ from_blanket_or_auto_impl,
45
+ cache,
46
+ ) ,
41
47
aliases : item. attrs . get_doc_aliases ( ) ,
42
48
} ) ;
43
49
}
@@ -192,12 +198,18 @@ pub(crate) fn build_index<'tcx>(
192
198
pub ( crate ) fn get_function_type_for_search < ' tcx > (
193
199
item : & clean:: Item ,
194
200
tcx : TyCtxt < ' tcx > ,
201
+ impl_generics : Option < & ( clean:: Type , clean:: Generics ) > ,
202
+ from_blanket_or_auto_impl : bool ,
195
203
cache : & Cache ,
196
204
) -> Option < IndexItemFunctionType > {
205
+ if from_blanket_or_auto_impl {
206
+ return None ;
207
+ }
208
+
197
209
let ( mut inputs, mut output) = match * item. kind {
198
- clean:: FunctionItem ( ref f) => get_fn_inputs_and_outputs ( f, tcx, cache) ,
199
- clean:: MethodItem ( ref m, _) => get_fn_inputs_and_outputs ( m, tcx, cache) ,
200
- clean:: TyMethodItem ( ref m) => get_fn_inputs_and_outputs ( m, tcx, cache) ,
210
+ clean:: FunctionItem ( ref f) => get_fn_inputs_and_outputs ( f, tcx, impl_generics , cache) ,
211
+ clean:: MethodItem ( ref m, _) => get_fn_inputs_and_outputs ( m, tcx, impl_generics , cache) ,
212
+ clean:: TyMethodItem ( ref m) => get_fn_inputs_and_outputs ( m, tcx, impl_generics , cache) ,
201
213
_ => return None ,
202
214
} ;
203
215
@@ -247,9 +259,10 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
247
259
/// Important note: It goes through generics recursively. So if you have
248
260
/// `T: Option<Result<(), ()>>`, it'll go into `Option` and then into `Result`.
249
261
#[ instrument( level = "trace" , skip( tcx, res, cache) ) ]
250
- fn add_generics_and_bounds_as_types < ' tcx > (
262
+ fn add_generics_and_bounds_as_types < ' tcx , ' a > (
263
+ self_ : Option < & ' a Type > ,
251
264
generics : & Generics ,
252
- arg : & Type ,
265
+ arg : & ' a Type ,
253
266
tcx : TyCtxt < ' tcx > ,
254
267
recurse : usize ,
255
268
res : & mut Vec < TypeWithKind > ,
@@ -334,6 +347,17 @@ fn add_generics_and_bounds_as_types<'tcx>(
334
347
return ;
335
348
}
336
349
350
+ // First, check if it's "Self".
351
+ let arg = if let Some ( self_) = self_ {
352
+ match & * arg {
353
+ Type :: BorrowedRef { type_, .. } if type_. is_self_type ( ) => self_,
354
+ type_ if type_. is_self_type ( ) => self_,
355
+ arg => arg,
356
+ }
357
+ } else {
358
+ arg
359
+ } ;
360
+
337
361
// If this argument is a type parameter and not a trait bound or a type, we need to look
338
362
// for its bounds.
339
363
if let Type :: Generic ( arg_s) = * arg {
@@ -350,6 +374,7 @@ fn add_generics_and_bounds_as_types<'tcx>(
350
374
match & param_def. kind {
351
375
clean:: GenericParamDefKind :: Type { default : Some ( ty) , .. } => {
352
376
add_generics_and_bounds_as_types (
377
+ self_,
353
378
generics,
354
379
ty,
355
380
tcx,
@@ -372,6 +397,7 @@ fn add_generics_and_bounds_as_types<'tcx>(
372
397
if let Some ( path) = bound. get_trait_path ( ) {
373
398
let ty = Type :: Path { path } ;
374
399
add_generics_and_bounds_as_types (
400
+ self_,
375
401
generics,
376
402
& ty,
377
403
tcx,
@@ -393,6 +419,7 @@ fn add_generics_and_bounds_as_types<'tcx>(
393
419
if let Some ( arg_generics) = arg. generics ( ) {
394
420
for gen in arg_generics. iter ( ) {
395
421
add_generics_and_bounds_as_types (
422
+ self_,
396
423
generics,
397
424
gen,
398
425
tcx,
@@ -413,18 +440,33 @@ fn add_generics_and_bounds_as_types<'tcx>(
413
440
fn get_fn_inputs_and_outputs < ' tcx > (
414
441
func : & Function ,
415
442
tcx : TyCtxt < ' tcx > ,
443
+ impl_generics : Option < & ( clean:: Type , clean:: Generics ) > ,
416
444
cache : & Cache ,
417
445
) -> ( Vec < TypeWithKind > , Vec < TypeWithKind > ) {
418
446
let decl = & func. decl ;
419
- let generics = & func. generics ;
447
+
448
+ let combined_generics;
449
+ let ( self_, generics) = if let Some ( & ( ref impl_self, ref impl_generics) ) = impl_generics {
450
+ match ( impl_generics. is_empty ( ) , func. generics . is_empty ( ) ) {
451
+ ( true , _) => ( Some ( impl_self) , & func. generics ) ,
452
+ ( _, true ) => ( Some ( impl_self) , impl_generics) ,
453
+ ( false , false ) => {
454
+ let mut params = func. generics . params . clone ( ) ;
455
+ params. extend ( impl_generics. params . clone ( ) ) ;
456
+ let mut where_predicates = func. generics . where_predicates . clone ( ) ;
457
+ where_predicates. extend ( impl_generics. where_predicates . clone ( ) ) ;
458
+ combined_generics = clean:: Generics { params, where_predicates } ;
459
+ ( Some ( impl_self) , & combined_generics)
460
+ }
461
+ }
462
+ } else {
463
+ ( None , & func. generics )
464
+ } ;
420
465
421
466
let mut all_types = Vec :: new ( ) ;
422
467
for arg in decl. inputs . values . iter ( ) {
423
- if arg. type_ . is_self_type ( ) {
424
- continue ;
425
- }
426
468
let mut args = Vec :: new ( ) ;
427
- add_generics_and_bounds_as_types ( generics, & arg. type_ , tcx, 0 , & mut args, cache) ;
469
+ add_generics_and_bounds_as_types ( self_ , generics, & arg. type_ , tcx, 0 , & mut args, cache) ;
428
470
if !args. is_empty ( ) {
429
471
all_types. extend ( args) ;
430
472
} else {
@@ -437,7 +479,15 @@ fn get_fn_inputs_and_outputs<'tcx>(
437
479
let mut ret_types = Vec :: new ( ) ;
438
480
match decl. output {
439
481
FnRetTy :: Return ( ref return_type) => {
440
- add_generics_and_bounds_as_types ( generics, return_type, tcx, 0 , & mut ret_types, cache) ;
482
+ add_generics_and_bounds_as_types (
483
+ self_,
484
+ generics,
485
+ return_type,
486
+ tcx,
487
+ 0 ,
488
+ & mut ret_types,
489
+ cache,
490
+ ) ;
441
491
if ret_types. is_empty ( ) {
442
492
if let Some ( kind) = return_type. def_id ( cache) . map ( |did| tcx. def_kind ( did) . into ( ) ) {
443
493
ret_types. push ( TypeWithKind :: from ( ( get_index_type ( return_type, vec ! [ ] ) , kind) ) ) ;
0 commit comments