@@ -104,6 +104,12 @@ impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
104104 }
105105}
106106
107+ impl < T , U > Clean < U > for ty:: Binder < T > where T : Clean < U > {
108+ fn clean ( & self , cx : & DocContext ) -> U {
109+ self . 0 . clean ( cx)
110+ }
111+ }
112+
107113impl < T : Clean < U > , U > Clean < Vec < U > > for syntax:: owned_slice:: OwnedSlice < T > {
108114 fn clean ( & self , cx : & DocContext ) -> Vec < U > {
109115 self . iter ( ) . map ( |x| x. clean ( cx) ) . collect ( )
@@ -498,22 +504,28 @@ impl Clean<TyParamBound> for ast::TyParamBound {
498504 }
499505}
500506
501- impl < ' tcx > Clean < Vec < TyParamBound > > for ty:: ExistentialBounds < ' tcx > {
502- fn clean ( & self , cx : & DocContext ) -> Vec < TyParamBound > {
503- let mut vec = vec ! [ ] ;
504- self . region_bound . clean ( cx) . map ( |b| vec . push ( RegionBound ( b) ) ) ;
507+ impl < ' tcx > Clean < ( Vec < TyParamBound > , Vec < TypeBinding > ) > for ty:: ExistentialBounds < ' tcx > {
508+ fn clean ( & self , cx : & DocContext ) -> ( Vec < TyParamBound > , Vec < TypeBinding > ) {
509+ let mut tp_bounds = vec ! [ ] ;
510+ self . region_bound . clean ( cx) . map ( |b| tp_bounds . push ( RegionBound ( b) ) ) ;
505511 for bb in self . builtin_bounds . iter ( ) {
506- vec . push ( bb. clean ( cx) ) ;
512+ tp_bounds . push ( bb. clean ( cx) ) ;
507513 }
508514
509- // FIXME(#20299) -- should do something with projection bounds
515+ let mut bindings = vec ! [ ] ;
516+ for & ty:: Binder ( ref pb) in self . projection_bounds . iter ( ) {
517+ bindings. push ( TypeBinding {
518+ name : pb. projection_ty . item_name . clean ( cx) ,
519+ ty : pb. ty . clean ( cx)
520+ } ) ;
521+ }
510522
511- vec
523+ ( tp_bounds , bindings )
512524 }
513525}
514526
515527fn external_path_params ( cx : & DocContext , trait_did : Option < ast:: DefId > ,
516- substs : & subst:: Substs ) -> PathParameters {
528+ bindings : Vec < TypeBinding > , substs : & subst:: Substs ) -> PathParameters {
517529 use rustc:: middle:: ty:: sty;
518530 let lifetimes = substs. regions ( ) . get_slice ( subst:: TypeSpace )
519531 . iter ( )
@@ -531,7 +543,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<ast::DefId>,
531543 return PathParameters :: AngleBracketed {
532544 lifetimes : lifetimes,
533545 types : types. clean ( cx) ,
534- bindings : vec ! [ ]
546+ bindings : bindings
535547 }
536548 }
537549 } ;
@@ -548,7 +560,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<ast::DefId>,
548560 PathParameters :: AngleBracketed {
549561 lifetimes : lifetimes,
550562 types : types. clean ( cx) ,
551- bindings : vec ! [ ] // FIXME(#20646)
563+ bindings : bindings
552564 }
553565 }
554566 }
@@ -557,12 +569,12 @@ fn external_path_params(cx: &DocContext, trait_did: Option<ast::DefId>,
557569// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
558570// from Fn<(A, B,), C> to Fn(A, B) -> C
559571fn external_path ( cx : & DocContext , name : & str , trait_did : Option < ast:: DefId > ,
560- substs : & subst:: Substs ) -> Path {
572+ bindings : Vec < TypeBinding > , substs : & subst:: Substs ) -> Path {
561573 Path {
562574 global : false ,
563575 segments : vec ! [ PathSegment {
564576 name: name. to_string( ) ,
565- params: external_path_params( cx, trait_did, substs)
577+ params: external_path_params( cx, trait_did, bindings , substs)
566578 } ] ,
567579 }
568580}
@@ -577,16 +589,16 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
577589 let ( did, path) = match * self {
578590 ty:: BoundSend =>
579591 ( tcx. lang_items . send_trait ( ) . unwrap ( ) ,
580- external_path ( cx, "Send" , None , & empty) ) ,
592+ external_path ( cx, "Send" , None , vec ! [ ] , & empty) ) ,
581593 ty:: BoundSized =>
582594 ( tcx. lang_items . sized_trait ( ) . unwrap ( ) ,
583- external_path ( cx, "Sized" , None , & empty) ) ,
595+ external_path ( cx, "Sized" , None , vec ! [ ] , & empty) ) ,
584596 ty:: BoundCopy =>
585597 ( tcx. lang_items . copy_trait ( ) . unwrap ( ) ,
586- external_path ( cx, "Copy" , None , & empty) ) ,
598+ external_path ( cx, "Copy" , None , vec ! [ ] , & empty) ) ,
587599 ty:: BoundSync =>
588600 ( tcx. lang_items . sync_trait ( ) . unwrap ( ) ,
589- external_path ( cx, "Sync" , None , & empty) ) ,
601+ external_path ( cx, "Sync" , None , vec ! [ ] , & empty) ) ,
590602 } ;
591603 let fqn = csearch:: get_item_path ( tcx, did) ;
592604 let fqn = fqn. into_iter ( ) . map ( |i| i. to_string ( ) ) . collect ( ) ;
@@ -603,12 +615,6 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
603615 }
604616}
605617
606- impl < ' tcx > Clean < TyParamBound > for ty:: PolyTraitRef < ' tcx > {
607- fn clean ( & self , cx : & DocContext ) -> TyParamBound {
608- self . 0 . clean ( cx)
609- }
610- }
611-
612618impl < ' tcx > Clean < TyParamBound > for ty:: TraitRef < ' tcx > {
613619 fn clean ( & self , cx : & DocContext ) -> TyParamBound {
614620 let tcx = match cx. tcx_opt ( ) {
@@ -619,7 +625,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
619625 let fqn = fqn. into_iter ( ) . map ( |i| i. to_string ( ) )
620626 . collect :: < Vec < String > > ( ) ;
621627 let path = external_path ( cx, fqn. last ( ) . unwrap ( ) . as_slice ( ) ,
622- Some ( self . def_id ) , self . substs ) ;
628+ Some ( self . def_id ) , vec ! [ ] , self . substs ) ;
623629 cx. external_paths . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . insert ( self . def_id ,
624630 ( fqn, TypeTrait ) ) ;
625631
@@ -730,8 +736,7 @@ impl Clean<Option<Lifetime>> for ty::Region {
730736pub enum WherePredicate {
731737 BoundPredicate { ty : Type , bounds : Vec < TyParamBound > } ,
732738 RegionPredicate { lifetime : Lifetime , bounds : Vec < Lifetime > } ,
733- // FIXME (#20041)
734- EqPredicate
739+ EqPredicate { lhs : Type , rhs : Type }
735740}
736741
737742impl Clean < WherePredicate > for ast:: WherePredicate {
@@ -752,12 +757,89 @@ impl Clean<WherePredicate> for ast::WherePredicate {
752757 }
753758
754759 ast:: WherePredicate :: EqPredicate ( _) => {
755- WherePredicate :: EqPredicate
760+ unimplemented ! ( ) // FIXME(#20041)
756761 }
757762 }
758763 }
759764}
760765
766+ impl < ' a > Clean < WherePredicate > for ty:: Predicate < ' a > {
767+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
768+ use rustc:: middle:: ty:: Predicate ;
769+
770+ match * self {
771+ Predicate :: Trait ( ref pred) => pred. clean ( cx) ,
772+ Predicate :: Equate ( ref pred) => pred. clean ( cx) ,
773+ Predicate :: RegionOutlives ( ref pred) => pred. clean ( cx) ,
774+ Predicate :: TypeOutlives ( ref pred) => pred. clean ( cx) ,
775+ Predicate :: Projection ( ref pred) => pred. clean ( cx)
776+ }
777+ }
778+ }
779+
780+ impl < ' a > Clean < WherePredicate > for ty:: TraitPredicate < ' a > {
781+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
782+ WherePredicate :: BoundPredicate {
783+ ty : self . trait_ref . substs . self_ty ( ) . clean ( cx) . unwrap ( ) ,
784+ bounds : vec ! [ self . trait_ref. clean( cx) ]
785+ }
786+ }
787+ }
788+
789+ impl < ' tcx > Clean < WherePredicate > for ty:: EquatePredicate < ' tcx > {
790+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
791+ let ty:: EquatePredicate ( ref lhs, ref rhs) = * self ;
792+ WherePredicate :: EqPredicate {
793+ lhs : lhs. clean ( cx) ,
794+ rhs : rhs. clean ( cx)
795+ }
796+ }
797+ }
798+
799+ impl Clean < WherePredicate > for ty:: OutlivesPredicate < ty:: Region , ty:: Region > {
800+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
801+ let ty:: OutlivesPredicate ( ref a, ref b) = * self ;
802+ WherePredicate :: RegionPredicate {
803+ lifetime : a. clean ( cx) . unwrap ( ) ,
804+ bounds : vec ! [ b. clean( cx) . unwrap( ) ]
805+ }
806+ }
807+ }
808+
809+ impl < ' tcx > Clean < WherePredicate > for ty:: OutlivesPredicate < ty:: Ty < ' tcx > , ty:: Region > {
810+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
811+ let ty:: OutlivesPredicate ( ref ty, ref lt) = * self ;
812+
813+ WherePredicate :: BoundPredicate {
814+ ty : ty. clean ( cx) ,
815+ bounds : vec ! [ TyParamBound :: RegionBound ( lt. clean( cx) . unwrap( ) ) ]
816+ }
817+ }
818+ }
819+
820+ impl < ' tcx > Clean < WherePredicate > for ty:: ProjectionPredicate < ' tcx > {
821+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
822+ WherePredicate :: EqPredicate {
823+ lhs : self . projection_ty . clean ( cx) ,
824+ rhs : self . ty . clean ( cx)
825+ }
826+ }
827+ }
828+
829+ impl < ' tcx > Clean < Type > for ty:: ProjectionTy < ' tcx > {
830+ fn clean ( & self , cx : & DocContext ) -> Type {
831+ let trait_ = match self . trait_ref . clean ( cx) {
832+ TyParamBound :: TraitBound ( t, _) => t. trait_ ,
833+ TyParamBound :: RegionBound ( _) => panic ! ( "cleaning a trait got a region??" ) ,
834+ } ;
835+ Type :: QPath {
836+ name : self . item_name . clean ( cx) ,
837+ self_type : box self . trait_ref . self_ty ( ) . clean ( cx) ,
838+ trait_ : box trait_
839+ }
840+ }
841+ }
842+
761843// maybe use a Generic enum and use ~[Generic]?
762844#[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Show ) ]
763845pub struct Generics {
@@ -778,11 +860,80 @@ impl Clean<Generics> for ast::Generics {
778860
779861impl < ' a , ' tcx > Clean < Generics > for ( & ' a ty:: Generics < ' tcx > , subst:: ParamSpace ) {
780862 fn clean ( & self , cx : & DocContext ) -> Generics {
781- let ( me, space) = * self ;
863+ use std:: collections:: HashSet ;
864+ use syntax:: ast:: TraitBoundModifier as TBM ;
865+ use self :: WherePredicate as WP ;
866+
867+ fn has_sized_bound ( bounds : & [ TyParamBound ] , cx : & DocContext ) -> bool {
868+ if let Some ( tcx) = cx. tcx_opt ( ) {
869+ let sized_did = match tcx. lang_items . sized_trait ( ) {
870+ Some ( did) => did,
871+ None => return false
872+ } ;
873+ for bound in bounds. iter ( ) {
874+ if let TyParamBound :: TraitBound ( PolyTrait {
875+ trait_ : Type :: ResolvedPath { did, .. } , ..
876+ } , TBM :: None ) = * bound {
877+ if did == sized_did {
878+ return true
879+ }
880+ }
881+ }
882+ }
883+ false
884+ }
885+
886+ let ( gens, space) = * self ;
887+ // Bounds in the type_params and lifetimes fields are repeated in the predicates
888+ // field (see rustc_typeck::collect::ty_generics), so remove them.
889+ let stripped_typarams = gens. types . get_slice ( space) . iter ( ) . map ( |tp| {
890+ let mut stp = tp. clone ( ) ;
891+ stp. bounds = ty:: ParamBounds :: empty ( ) ;
892+ stp. clean ( cx)
893+ } ) . collect :: < Vec < _ > > ( ) ;
894+ let stripped_lifetimes = gens. regions . get_slice ( space) . iter ( ) . map ( |rp| {
895+ let mut srp = rp. clone ( ) ;
896+ srp. bounds = Vec :: new ( ) ;
897+ srp. clean ( cx)
898+ } ) . collect :: < Vec < _ > > ( ) ;
899+
900+ let where_predicates = gens. predicates . get_slice ( space) . to_vec ( ) . clean ( cx) ;
901+ // Type parameters have a Sized bound by default unless removed with ?Sized.
902+ // Scan through the predicates and mark any type parameter with a Sized
903+ // bound, removing the bounds as we find them.
904+ let mut sized_params = HashSet :: new ( ) ;
905+ let mut where_predicates = where_predicates. into_iter ( ) . filter_map ( |pred| {
906+ if let WP :: BoundPredicate { ty : Type :: Generic ( ref g) , ref bounds } = pred {
907+ if has_sized_bound ( & * * bounds, cx) {
908+ sized_params. insert ( g. clone ( ) ) ;
909+ return None
910+ }
911+ }
912+ Some ( pred)
913+ } ) . collect :: < Vec < _ > > ( ) ;
914+ // Finally, run through the type parameters again and insert a ?Sized unbound for
915+ // any we didn't find to be Sized.
916+ for tp in stripped_typarams. iter ( ) {
917+ if !sized_params. contains ( & tp. name ) {
918+ let mut sized_bound = ty:: BuiltinBound :: BoundSized . clean ( cx) ;
919+ if let TyParamBound :: TraitBound ( _, ref mut tbm) = sized_bound {
920+ * tbm = TBM :: Maybe
921+ } ;
922+ where_predicates. push ( WP :: BoundPredicate {
923+ ty : Type :: Generic ( tp. name . clone ( ) ) ,
924+ bounds : vec ! [ sized_bound]
925+ } )
926+ }
927+ }
928+
929+ // It would be nice to collect all of the bounds on a type and recombine
930+ // them if possible, to avoid e.g. `where T: Foo, T: Bar, T: Sized, T: 'a`
931+ // and instead see `where T: Foo + Bar + Sized + 'a`
932+
782933 Generics {
783- type_params : me . types . get_slice ( space ) . to_vec ( ) . clean ( cx ) ,
784- lifetimes : me . regions . get_slice ( space ) . to_vec ( ) . clean ( cx ) ,
785- where_predicates : vec ! [ ]
934+ type_params : stripped_typarams ,
935+ lifetimes : stripped_lifetimes ,
936+ where_predicates : where_predicates
786937 }
787938 }
788939}
@@ -910,27 +1061,6 @@ impl Clean<Item> for doctree::Function {
9101061 }
9111062}
9121063
913- #[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Show ) ]
914- pub struct ClosureDecl {
915- pub lifetimes : Vec < Lifetime > ,
916- pub decl : FnDecl ,
917- pub onceness : ast:: Onceness ,
918- pub unsafety : ast:: Unsafety ,
919- pub bounds : Vec < TyParamBound > ,
920- }
921-
922- impl Clean < ClosureDecl > for ast:: ClosureTy {
923- fn clean ( & self , cx : & DocContext ) -> ClosureDecl {
924- ClosureDecl {
925- lifetimes : self . lifetimes . clean ( cx) ,
926- decl : self . decl . clean ( cx) ,
927- onceness : self . onceness ,
928- unsafety : self . unsafety ,
929- bounds : self . bounds . clean ( cx)
930- }
931- }
932- }
933-
9341064#[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Show ) ]
9351065pub struct FnDecl {
9361066 pub inputs : Arguments ,
@@ -1207,8 +1337,6 @@ pub enum Type {
12071337 Generic ( String ) ,
12081338 /// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
12091339 Primitive ( PrimitiveType ) ,
1210- Closure ( Box < ClosureDecl > ) ,
1211- Proc ( Box < ClosureDecl > ) ,
12121340 /// extern "ABI" fn
12131341 BareFunction ( Box < BareFunctionDecl > ) ,
12141342 Tuple ( Vec < Type > ) ,
@@ -1436,7 +1564,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
14361564 _ => TypeEnum ,
14371565 } ;
14381566 let path = external_path ( cx, fqn. last ( ) . unwrap ( ) . to_string ( ) . as_slice ( ) ,
1439- None , substs) ;
1567+ None , vec ! [ ] , substs) ;
14401568 cx. external_paths . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . insert ( did, ( fqn, kind) ) ;
14411569 ResolvedPath {
14421570 path : path,
@@ -1448,12 +1576,13 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
14481576 let did = principal. def_id ( ) ;
14491577 let fqn = csearch:: get_item_path ( cx. tcx ( ) , did) ;
14501578 let fqn: Vec < _ > = fqn. into_iter ( ) . map ( |i| i. to_string ( ) ) . collect ( ) ;
1579+ let ( typarams, bindings) = bounds. clean ( cx) ;
14511580 let path = external_path ( cx, fqn. last ( ) . unwrap ( ) . to_string ( ) . as_slice ( ) ,
1452- Some ( did) , principal. substs ( ) ) ;
1581+ Some ( did) , bindings , principal. substs ( ) ) ;
14531582 cx. external_paths . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . insert ( did, ( fqn, TypeTrait ) ) ;
14541583 ResolvedPath {
14551584 path : path,
1456- typarams : Some ( bounds . clean ( cx ) ) ,
1585+ typarams : Some ( typarams ) ,
14571586 did : did,
14581587 }
14591588 }
0 commit comments