@@ -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 ( )
@@ -498,22 +504,28 @@ impl Clean<TyParamBound> for ast::TyParamBound {
498
504
}
499
505
}
500
506
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) ) ) ;
505
511
for bb in self . builtin_bounds . iter ( ) {
506
- vec . push ( bb. clean ( cx) ) ;
512
+ tp_bounds . push ( bb. clean ( cx) ) ;
507
513
}
508
514
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
+ }
510
522
511
- vec
523
+ ( tp_bounds , bindings )
512
524
}
513
525
}
514
526
515
527
fn external_path_params ( cx : & DocContext , trait_did : Option < ast:: DefId > ,
516
- substs : & subst:: Substs ) -> PathParameters {
528
+ bindings : Vec < TypeBinding > , substs : & subst:: Substs ) -> PathParameters {
517
529
use rustc:: middle:: ty:: sty;
518
530
let lifetimes = substs. regions ( ) . get_slice ( subst:: TypeSpace )
519
531
. iter ( )
@@ -531,7 +543,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<ast::DefId>,
531
543
return PathParameters :: AngleBracketed {
532
544
lifetimes : lifetimes,
533
545
types : types. clean ( cx) ,
534
- bindings : vec ! [ ]
546
+ bindings : bindings
535
547
}
536
548
}
537
549
} ;
@@ -548,7 +560,7 @@ fn external_path_params(cx: &DocContext, trait_did: Option<ast::DefId>,
548
560
PathParameters :: AngleBracketed {
549
561
lifetimes : lifetimes,
550
562
types : types. clean ( cx) ,
551
- bindings : vec ! [ ] // FIXME(#20646)
563
+ bindings : bindings
552
564
}
553
565
}
554
566
}
@@ -557,12 +569,12 @@ fn external_path_params(cx: &DocContext, trait_did: Option<ast::DefId>,
557
569
// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar
558
570
// from Fn<(A, B,), C> to Fn(A, B) -> C
559
571
fn external_path ( cx : & DocContext , name : & str , trait_did : Option < ast:: DefId > ,
560
- substs : & subst:: Substs ) -> Path {
572
+ bindings : Vec < TypeBinding > , substs : & subst:: Substs ) -> Path {
561
573
Path {
562
574
global : false ,
563
575
segments : vec ! [ PathSegment {
564
576
name: name. to_string( ) ,
565
- params: external_path_params( cx, trait_did, substs)
577
+ params: external_path_params( cx, trait_did, bindings , substs)
566
578
} ] ,
567
579
}
568
580
}
@@ -577,16 +589,16 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
577
589
let ( did, path) = match * self {
578
590
ty:: BoundSend =>
579
591
( tcx. lang_items . send_trait ( ) . unwrap ( ) ,
580
- external_path ( cx, "Send" , None , & empty) ) ,
592
+ external_path ( cx, "Send" , None , vec ! [ ] , & empty) ) ,
581
593
ty:: BoundSized =>
582
594
( tcx. lang_items . sized_trait ( ) . unwrap ( ) ,
583
- external_path ( cx, "Sized" , None , & empty) ) ,
595
+ external_path ( cx, "Sized" , None , vec ! [ ] , & empty) ) ,
584
596
ty:: BoundCopy =>
585
597
( tcx. lang_items . copy_trait ( ) . unwrap ( ) ,
586
- external_path ( cx, "Copy" , None , & empty) ) ,
598
+ external_path ( cx, "Copy" , None , vec ! [ ] , & empty) ) ,
587
599
ty:: BoundSync =>
588
600
( tcx. lang_items . sync_trait ( ) . unwrap ( ) ,
589
- external_path ( cx, "Sync" , None , & empty) ) ,
601
+ external_path ( cx, "Sync" , None , vec ! [ ] , & empty) ) ,
590
602
} ;
591
603
let fqn = csearch:: get_item_path ( tcx, did) ;
592
604
let fqn = fqn. into_iter ( ) . map ( |i| i. to_string ( ) ) . collect ( ) ;
@@ -603,12 +615,6 @@ impl Clean<TyParamBound> for ty::BuiltinBound {
603
615
}
604
616
}
605
617
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
618
impl < ' tcx > Clean < TyParamBound > for ty:: TraitRef < ' tcx > {
613
619
fn clean ( & self , cx : & DocContext ) -> TyParamBound {
614
620
let tcx = match cx. tcx_opt ( ) {
@@ -619,7 +625,7 @@ impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
619
625
let fqn = fqn. into_iter ( ) . map ( |i| i. to_string ( ) )
620
626
. collect :: < Vec < String > > ( ) ;
621
627
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 ) ;
623
629
cx. external_paths . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . insert ( self . def_id ,
624
630
( fqn, TypeTrait ) ) ;
625
631
@@ -730,8 +736,7 @@ impl Clean<Option<Lifetime>> for ty::Region {
730
736
pub enum WherePredicate {
731
737
BoundPredicate { ty : Type , bounds : Vec < TyParamBound > } ,
732
738
RegionPredicate { lifetime : Lifetime , bounds : Vec < Lifetime > } ,
733
- // FIXME (#20041)
734
- EqPredicate
739
+ EqPredicate { lhs : Type , rhs : Type }
735
740
}
736
741
737
742
impl Clean < WherePredicate > for ast:: WherePredicate {
@@ -752,12 +757,89 @@ impl Clean<WherePredicate> for ast::WherePredicate {
752
757
}
753
758
754
759
ast:: WherePredicate :: EqPredicate ( _) => {
755
- WherePredicate :: EqPredicate
760
+ unimplemented ! ( ) // FIXME(#20041)
756
761
}
757
762
}
758
763
}
759
764
}
760
765
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
+
761
843
// maybe use a Generic enum and use ~[Generic]?
762
844
#[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Show ) ]
763
845
pub struct Generics {
@@ -778,11 +860,80 @@ impl Clean<Generics> for ast::Generics {
778
860
779
861
impl < ' a , ' tcx > Clean < Generics > for ( & ' a ty:: Generics < ' tcx > , subst:: ParamSpace ) {
780
862
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
+
782
933
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
786
937
}
787
938
}
788
939
}
@@ -910,27 +1061,6 @@ impl Clean<Item> for doctree::Function {
910
1061
}
911
1062
}
912
1063
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
-
934
1064
#[ derive( Clone , RustcEncodable , RustcDecodable , PartialEq , Show ) ]
935
1065
pub struct FnDecl {
936
1066
pub inputs : Arguments ,
@@ -1207,8 +1337,6 @@ pub enum Type {
1207
1337
Generic ( String ) ,
1208
1338
/// Primitives are just the fixed-size numeric types (plus int/uint/float), and char.
1209
1339
Primitive ( PrimitiveType ) ,
1210
- Closure ( Box < ClosureDecl > ) ,
1211
- Proc ( Box < ClosureDecl > ) ,
1212
1340
/// extern "ABI" fn
1213
1341
BareFunction ( Box < BareFunctionDecl > ) ,
1214
1342
Tuple ( Vec < Type > ) ,
@@ -1436,7 +1564,7 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
1436
1564
_ => TypeEnum ,
1437
1565
} ;
1438
1566
let path = external_path ( cx, fqn. last ( ) . unwrap ( ) . to_string ( ) . as_slice ( ) ,
1439
- None , substs) ;
1567
+ None , vec ! [ ] , substs) ;
1440
1568
cx. external_paths . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . insert ( did, ( fqn, kind) ) ;
1441
1569
ResolvedPath {
1442
1570
path : path,
@@ -1448,12 +1576,13 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
1448
1576
let did = principal. def_id ( ) ;
1449
1577
let fqn = csearch:: get_item_path ( cx. tcx ( ) , did) ;
1450
1578
let fqn: Vec < _ > = fqn. into_iter ( ) . map ( |i| i. to_string ( ) ) . collect ( ) ;
1579
+ let ( typarams, bindings) = bounds. clean ( cx) ;
1451
1580
let path = external_path ( cx, fqn. last ( ) . unwrap ( ) . to_string ( ) . as_slice ( ) ,
1452
- Some ( did) , principal. substs ( ) ) ;
1581
+ Some ( did) , bindings , principal. substs ( ) ) ;
1453
1582
cx. external_paths . borrow_mut ( ) . as_mut ( ) . unwrap ( ) . insert ( did, ( fqn, TypeTrait ) ) ;
1454
1583
ResolvedPath {
1455
1584
path : path,
1456
- typarams : Some ( bounds . clean ( cx ) ) ,
1585
+ typarams : Some ( typarams ) ,
1457
1586
did : did,
1458
1587
}
1459
1588
}
0 commit comments