@@ -104,6 +104,12 @@ impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
104
104
}
105
105
}
106
106
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
+
107
113
impl < T : Clean < U > , U > Clean < Vec < U > > for syntax:: owned_slice:: OwnedSlice < T > {
108
114
fn clean ( & self , cx : & DocContext ) -> Vec < U > {
109
115
self . iter ( ) . map ( |x| x. clean ( cx) ) . collect ( )
@@ -603,12 +609,6 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
603
609
}
604
610
}
605
611
606
- impl < ' tcx > Clean < TyParamBound > for ty:: PolyTraitRef < ' tcx > {
607
- fn clean ( & self , cx : & DocContext ) -> TyParamBound {
608
- self . 0 . clean ( cx)
609
- }
610
- }
611
-
612
612
impl < ' tcx > Clean < TyParamBound > for ty:: TraitRef < ' tcx > {
613
613
fn clean ( & self , cx : & DocContext ) -> TyParamBound {
614
614
let tcx = match cx. tcx_opt ( ) {
@@ -730,8 +730,7 @@ impl Clean<Option<Lifetime>> for ty::Region {
730
730
pub enum WherePredicate {
731
731
BoundPredicate { ty : Type , bounds : Vec < TyParamBound > } ,
732
732
RegionPredicate { lifetime : Lifetime , bounds : Vec < Lifetime > } ,
733
- // FIXME (#20041)
734
- EqPredicate
733
+ EqPredicate { lhs : Type , rhs : Type }
735
734
}
736
735
737
736
impl Clean < WherePredicate > for ast:: WherePredicate {
@@ -752,12 +751,89 @@ impl Clean<WherePredicate> for ast::WherePredicate {
752
751
}
753
752
754
753
ast:: WherePredicate :: EqPredicate ( _) => {
755
- WherePredicate :: EqPredicate
754
+ unimplemented ! ( ) // FIXME(#20041)
756
755
}
757
756
}
758
757
}
759
758
}
760
759
760
+ impl < ' a > Clean < WherePredicate > for ty:: Predicate < ' a > {
761
+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
762
+ use rustc:: middle:: ty:: Predicate ;
763
+
764
+ match * self {
765
+ Predicate :: Trait ( ref pred) => pred. clean ( cx) ,
766
+ Predicate :: Equate ( ref pred) => pred. clean ( cx) ,
767
+ Predicate :: RegionOutlives ( ref pred) => pred. clean ( cx) ,
768
+ Predicate :: TypeOutlives ( ref pred) => pred. clean ( cx) ,
769
+ Predicate :: Projection ( ref pred) => pred. clean ( cx)
770
+ }
771
+ }
772
+ }
773
+
774
+ impl < ' a > Clean < WherePredicate > for ty:: TraitPredicate < ' a > {
775
+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
776
+ WherePredicate :: BoundPredicate {
777
+ ty : self . trait_ref . substs . self_ty ( ) . clean ( cx) . unwrap ( ) ,
778
+ bounds : vec ! [ self . trait_ref. clean( cx) ]
779
+ }
780
+ }
781
+ }
782
+
783
+ impl < ' tcx > Clean < WherePredicate > for ty:: EquatePredicate < ' tcx > {
784
+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
785
+ let ty:: EquatePredicate ( ref lhs, ref rhs) = * self ;
786
+ WherePredicate :: EqPredicate {
787
+ lhs : lhs. clean ( cx) ,
788
+ rhs : rhs. clean ( cx)
789
+ }
790
+ }
791
+ }
792
+
793
+ impl Clean < WherePredicate > for ty:: OutlivesPredicate < ty:: Region , ty:: Region > {
794
+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
795
+ let ty:: OutlivesPredicate ( ref a, ref b) = * self ;
796
+ WherePredicate :: RegionPredicate {
797
+ lifetime : a. clean ( cx) . unwrap ( ) ,
798
+ bounds : vec ! [ b. clean( cx) . unwrap( ) ]
799
+ }
800
+ }
801
+ }
802
+
803
+ impl < ' tcx > Clean < WherePredicate > for ty:: OutlivesPredicate < ty:: Ty < ' tcx > , ty:: Region > {
804
+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
805
+ let ty:: OutlivesPredicate ( ref ty, ref lt) = * self ;
806
+
807
+ WherePredicate :: BoundPredicate {
808
+ ty : ty. clean ( cx) ,
809
+ bounds : vec ! [ TyParamBound :: RegionBound ( lt. clean( cx) . unwrap( ) ) ]
810
+ }
811
+ }
812
+ }
813
+
814
+ impl < ' tcx > Clean < WherePredicate > for ty:: ProjectionPredicate < ' tcx > {
815
+ fn clean ( & self , cx : & DocContext ) -> WherePredicate {
816
+ WherePredicate :: EqPredicate {
817
+ lhs : self . projection_ty . clean ( cx) ,
818
+ rhs : self . ty . clean ( cx)
819
+ }
820
+ }
821
+ }
822
+
823
+ impl < ' tcx > Clean < Type > for ty:: ProjectionTy < ' tcx > {
824
+ fn clean ( & self , cx : & DocContext ) -> Type {
825
+ let trait_ = match self . trait_ref . clean ( cx) {
826
+ TyParamBound :: TraitBound ( t, _) => t. trait_ ,
827
+ TyParamBound :: RegionBound ( _) => panic ! ( "cleaning a trait got a region??" ) ,
828
+ } ;
829
+ Type :: QPath {
830
+ name : self . item_name . clean ( cx) ,
831
+ self_type : box self . trait_ref . self_ty ( ) . clean ( cx) ,
832
+ trait_ : box trait_
833
+ }
834
+ }
835
+ }
836
+
761
837
// maybe use a Generic enum and use ~[Generic]?
762
838
#[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Show ) ]
763
839
pub struct Generics {
@@ -778,11 +854,80 @@ impl Clean<Generics> for ast::Generics {
778
854
779
855
impl < ' a , ' tcx > Clean < Generics > for ( & ' a ty:: Generics < ' tcx > , subst:: ParamSpace ) {
780
856
fn clean ( & self , cx : & DocContext ) -> Generics {
781
- let ( me, space) = * self ;
857
+ use std:: collections:: HashSet ;
858
+ use syntax:: ast:: TraitBoundModifier as TBM ;
859
+ use self :: WherePredicate as WP ;
860
+
861
+ fn has_sized_bound ( bounds : & [ TyParamBound ] , cx : & DocContext ) -> bool {
862
+ if let Some ( tcx) = cx. tcx_opt ( ) {
863
+ let sized_did = match tcx. lang_items . sized_trait ( ) {
864
+ Some ( did) => did,
865
+ None => return false
866
+ } ;
867
+ for bound in bounds. iter ( ) {
868
+ if let TyParamBound :: TraitBound ( PolyTrait {
869
+ trait_ : Type :: ResolvedPath { did, .. } , ..
870
+ } , TBM :: None ) = * bound {
871
+ if did == sized_did {
872
+ return true
873
+ }
874
+ }
875
+ }
876
+ }
877
+ false
878
+ }
879
+
880
+ let ( gens, space) = * self ;
881
+ // Bounds in the type_params and lifetimes fields are repeated in the predicates
882
+ // field (see rustc_typeck::collect::ty_generics), so remove them.
883
+ let stripped_typarams = gens. types . get_slice ( space) . iter ( ) . map ( |tp| {
884
+ let mut stp = tp. clone ( ) ;
885
+ stp. bounds = ty:: ParamBounds :: empty ( ) ;
886
+ stp. clean ( cx)
887
+ } ) . collect :: < Vec < _ > > ( ) ;
888
+ let stripped_lifetimes = gens. regions . get_slice ( space) . iter ( ) . map ( |rp| {
889
+ let mut srp = rp. clone ( ) ;
890
+ srp. bounds = Vec :: new ( ) ;
891
+ srp. clean ( cx)
892
+ } ) . collect :: < Vec < _ > > ( ) ;
893
+
894
+ let where_predicates = gens. predicates . get_slice ( space) . to_vec ( ) . clean ( cx) ;
895
+ // Type parameters have a Sized bound by default unless removed with ?Sized.
896
+ // Scan through the predicates and mark any type parameter with a Sized
897
+ // bound, removing the bounds as we find them.
898
+ let mut sized_params = HashSet :: new ( ) ;
899
+ let mut where_predicates = where_predicates. into_iter ( ) . filter_map ( |pred| {
900
+ if let WP :: BoundPredicate { ty : Type :: Generic ( ref g) , ref bounds } = pred {
901
+ if has_sized_bound ( & * * bounds, cx) {
902
+ sized_params. insert ( g. clone ( ) ) ;
903
+ return None
904
+ }
905
+ }
906
+ Some ( pred)
907
+ } ) . collect :: < Vec < _ > > ( ) ;
908
+ // Finally, run through the type parameters again and insert a ?Sized unbound for
909
+ // any we didn't find to be Sized.
910
+ for tp in stripped_typarams. iter ( ) {
911
+ if !sized_params. contains ( & tp. name ) {
912
+ let mut sized_bound = ty:: BuiltinBound :: BoundSized . clean ( cx) ;
913
+ if let TyParamBound :: TraitBound ( _, ref mut tbm) = sized_bound {
914
+ * tbm = TBM :: Maybe
915
+ } ;
916
+ where_predicates. push ( WP :: BoundPredicate {
917
+ ty : Type :: Generic ( tp. name . clone ( ) ) ,
918
+ bounds : vec ! [ sized_bound]
919
+ } )
920
+ }
921
+ }
922
+
923
+ // It would be nice to collect all of the bounds on a type and recombine
924
+ // them if possible, to avoid e.g. `where T: Foo, T: Bar, T: Sized, T: 'a`
925
+ // and instead see `where T: Foo + Bar + Sized + 'a`
926
+
782
927
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 ! [ ]
928
+ type_params : stripped_typarams ,
929
+ lifetimes : stripped_lifetimes ,
930
+ where_predicates : where_predicates
786
931
}
787
932
}
788
933
}
0 commit comments