@@ -25,7 +25,7 @@ pub(crate) fn build_index<'tcx>(
2525
2626 // Attach all orphan items to the type's definition if the type
2727 // 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 {
2929 if let Some ( & ( ref fqp, _) ) = cache. paths . get ( & did) {
3030 let desc = item
3131 . doc_value ( )
@@ -37,7 +37,13 @@ pub(crate) fn build_index<'tcx>(
3737 desc,
3838 parent : Some ( did) ,
3939 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+ ) ,
4147 aliases : item. attrs . get_doc_aliases ( ) ,
4248 } ) ;
4349 }
@@ -192,12 +198,18 @@ pub(crate) fn build_index<'tcx>(
192198pub ( crate ) fn get_function_type_for_search < ' tcx > (
193199 item : & clean:: Item ,
194200 tcx : TyCtxt < ' tcx > ,
201+ impl_generics : Option < & ( clean:: Type , clean:: Generics ) > ,
202+ from_blanket_or_auto_impl : bool ,
195203 cache : & Cache ,
196204) -> Option < IndexItemFunctionType > {
205+ if from_blanket_or_auto_impl {
206+ return None ;
207+ }
208+
197209 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) ,
201213 _ => return None ,
202214 } ;
203215
@@ -247,9 +259,10 @@ fn get_index_type_name(clean_type: &clean::Type) -> Option<Symbol> {
247259/// Important note: It goes through generics recursively. So if you have
248260/// `T: Option<Result<(), ()>>`, it'll go into `Option` and then into `Result`.
249261#[ 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 > ,
251264 generics : & Generics ,
252- arg : & Type ,
265+ arg : & ' a Type ,
253266 tcx : TyCtxt < ' tcx > ,
254267 recurse : usize ,
255268 res : & mut Vec < TypeWithKind > ,
@@ -334,6 +347,17 @@ fn add_generics_and_bounds_as_types<'tcx>(
334347 return ;
335348 }
336349
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+
337361 // If this argument is a type parameter and not a trait bound or a type, we need to look
338362 // for its bounds.
339363 if let Type :: Generic ( arg_s) = * arg {
@@ -350,6 +374,7 @@ fn add_generics_and_bounds_as_types<'tcx>(
350374 match & param_def. kind {
351375 clean:: GenericParamDefKind :: Type { default : Some ( ty) , .. } => {
352376 add_generics_and_bounds_as_types (
377+ self_,
353378 generics,
354379 ty,
355380 tcx,
@@ -372,6 +397,7 @@ fn add_generics_and_bounds_as_types<'tcx>(
372397 if let Some ( path) = bound. get_trait_path ( ) {
373398 let ty = Type :: Path { path } ;
374399 add_generics_and_bounds_as_types (
400+ self_,
375401 generics,
376402 & ty,
377403 tcx,
@@ -393,6 +419,7 @@ fn add_generics_and_bounds_as_types<'tcx>(
393419 if let Some ( arg_generics) = arg. generics ( ) {
394420 for gen in arg_generics. iter ( ) {
395421 add_generics_and_bounds_as_types (
422+ self_,
396423 generics,
397424 gen,
398425 tcx,
@@ -413,18 +440,33 @@ fn add_generics_and_bounds_as_types<'tcx>(
413440fn get_fn_inputs_and_outputs < ' tcx > (
414441 func : & Function ,
415442 tcx : TyCtxt < ' tcx > ,
443+ impl_generics : Option < & ( clean:: Type , clean:: Generics ) > ,
416444 cache : & Cache ,
417445) -> ( Vec < TypeWithKind > , Vec < TypeWithKind > ) {
418446 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+ } ;
420465
421466 let mut all_types = Vec :: new ( ) ;
422467 for arg in decl. inputs . values . iter ( ) {
423- if arg. type_ . is_self_type ( ) {
424- continue ;
425- }
426468 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) ;
428470 if !args. is_empty ( ) {
429471 all_types. extend ( args) ;
430472 } else {
@@ -437,7 +479,15 @@ fn get_fn_inputs_and_outputs<'tcx>(
437479 let mut ret_types = Vec :: new ( ) ;
438480 match decl. output {
439481 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+ ) ;
441491 if ret_types. is_empty ( ) {
442492 if let Some ( kind) = return_type. def_id ( cache) . map ( |did| tcx. def_kind ( did) . into ( ) ) {
443493 ret_types. push ( TypeWithKind :: from ( ( get_index_type ( return_type, vec ! [ ] ) , kind) ) ) ;
0 commit comments