@@ -515,21 +515,55 @@ impl Clean<Vec<TyParamBound>> for ty::ExistentialBounds {
515515 }
516516}
517517
518- fn external_path ( cx : & DocContext , name : & str , substs : & subst:: Substs ) -> Path {
518+ fn external_path_params ( cx : & DocContext , trait_did : Option < ast:: DefId > ,
519+ substs : & subst:: Substs ) -> PathParameters {
520+ use rustc:: middle:: ty:: sty;
519521 let lifetimes = substs. regions ( ) . get_slice ( subst:: TypeSpace )
520522 . iter ( )
521523 . filter_map ( |v| v. clean ( cx) )
522524 . collect ( ) ;
523525 let types = substs. types . get_slice ( subst:: TypeSpace ) . to_vec ( ) ;
524- let types = types. clean ( cx) ;
526+
527+ match ( trait_did, cx. tcx_opt ( ) ) {
528+ // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
529+ ( Some ( did) , Some ( ref tcx) ) if tcx. lang_items . fn_trait_kind ( did) . is_some ( ) => {
530+ assert_eq ! ( types. len( ) , 2 ) ;
531+ let inputs = match types[ 0 ] . sty {
532+ sty:: ty_tup( ref tys) => tys. iter ( ) . map ( |t| t. clean ( cx) ) . collect ( ) ,
533+ _ => {
534+ return PathParameters :: AngleBracketed {
535+ lifetimes : lifetimes,
536+ types : types. clean ( cx)
537+ }
538+ }
539+ } ;
540+ let output = match types[ 1 ] . sty {
541+ sty:: ty_tup( ref v) if v. is_empty ( ) => None , // -> ()
542+ _ => Some ( types[ 1 ] . clean ( cx) )
543+ } ;
544+ PathParameters :: Parenthesized {
545+ inputs : inputs,
546+ output : output
547+ }
548+ } ,
549+ ( _, _) => {
550+ PathParameters :: AngleBracketed {
551+ lifetimes : lifetimes,
552+ types : types. clean ( cx) ,
553+ }
554+ }
555+ }
556+ }
557+
558+ // trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
559+ // from Fn<(A, B,), C> to Fn(A, B) -> C
560+ fn external_path ( cx : & DocContext , name : & str , trait_did : Option < ast:: DefId > ,
561+ substs : & subst:: Substs ) -> Path {
525562 Path {
526563 global : false ,
527564 segments : vec ! [ PathSegment {
528565 name: name. to_string( ) ,
529- params: PathParameters :: AngleBracketed {
530- lifetimes: lifetimes,
531- types: types,
532- }
566+ params: external_path_params( cx, trait_did, substs)
533567 } ] ,
534568 }
535569}
@@ -544,16 +578,16 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
544578 let ( did, path) = match * self {
545579 ty:: BoundSend =>
546580 ( tcx. lang_items . send_trait ( ) . unwrap ( ) ,
547- external_path ( cx, "Send" , & empty) ) ,
581+ external_path ( cx, "Send" , None , & empty) ) ,
548582 ty:: BoundSized =>
549583 ( tcx. lang_items . sized_trait ( ) . unwrap ( ) ,
550- external_path ( cx, "Sized" , & empty) ) ,
584+ external_path ( cx, "Sized" , None , & empty) ) ,
551585 ty:: BoundCopy =>
552586 ( tcx. lang_items . copy_trait ( ) . unwrap ( ) ,
553- external_path ( cx, "Copy" , & empty) ) ,
587+ external_path ( cx, "Copy" , None , & empty) ) ,
554588 ty:: BoundSync =>
555589 ( tcx. lang_items . sync_trait ( ) . unwrap ( ) ,
556- external_path ( cx, "Sync" , & empty) ) ,
590+ external_path ( cx, "Sync" , None , & empty) ) ,
557591 } ;
558592 let fqn = csearch:: get_item_path ( tcx, did) ;
559593 let fqn = fqn. into_iter ( ) . map ( |i| i. to_string ( ) ) . collect ( ) ;
@@ -586,7 +620,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
586620 let fqn = fqn. into_iter ( ) . map ( |i| i. to_string ( ) )
587621 . collect :: < Vec < String > > ( ) ;
588622 let path = external_path ( cx, fqn. last ( ) . unwrap ( ) . as_slice ( ) ,
589- & self . substs ) ;
623+ Some ( self . def_id ) , & self . substs ) ;
590624 cx. external_paths . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . insert ( self . def_id ,
591625 ( fqn, TypeTrait ) ) ;
592626
@@ -1437,7 +1471,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
14371471 _ => TypeEnum ,
14381472 } ;
14391473 let path = external_path ( cx, fqn. last ( ) . unwrap ( ) . to_string ( ) . as_slice ( ) ,
1440- substs) ;
1474+ None , substs) ;
14411475 cx. external_paths . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . insert ( did, ( fqn, kind) ) ;
14421476 ResolvedPath {
14431477 path : path,
0 commit comments