@@ -734,6 +734,33 @@ impl TyParamBound {
734
734
}
735
735
false
736
736
}
737
+
738
+ fn maybe_dynsized ( cx : & DocContext ) -> TyParamBound {
739
+ let did = cx. tcx . require_lang_item ( lang_items:: DynSizedTraitLangItem ) ;
740
+ let empty = cx. tcx . intern_substs ( & [ ] ) ;
741
+ let path = external_path ( cx, & cx. tcx . item_name ( did) ,
742
+ Some ( did) , false , vec ! [ ] , empty) ;
743
+ inline:: record_extern_fqn ( cx, did, TypeKind :: Trait ) ;
744
+ TraitBound ( PolyTrait {
745
+ trait_ : ResolvedPath {
746
+ path,
747
+ typarams : None ,
748
+ did,
749
+ is_generic : false ,
750
+ } ,
751
+ lifetimes : vec ! [ ]
752
+ } , hir:: TraitBoundModifier :: Maybe )
753
+ }
754
+
755
+ fn is_dynsized_bound ( & self , cx : & DocContext ) -> bool {
756
+ use rustc:: hir:: TraitBoundModifier as TBM ;
757
+ if let TyParamBound :: TraitBound ( PolyTrait { ref trait_, .. } , TBM :: None ) = * self {
758
+ if trait_. def_id ( ) == cx. tcx . lang_items ( ) . dynsized_trait ( ) {
759
+ return true ;
760
+ }
761
+ }
762
+ false
763
+ }
737
764
}
738
765
739
766
impl Clean < TyParamBound > for hir:: TyParamBound {
@@ -1089,36 +1116,47 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
1089
1116
1090
1117
let mut where_predicates = preds. predicates . to_vec ( ) . clean ( cx) ;
1091
1118
1092
- // Type parameters and have a Sized bound by default unless removed with
1093
- // ?Sized. Scan through the predicates and mark any type parameter with
1094
- // a Sized bound, removing the bounds as we find them.
1119
+ // Type parameters have a Sized bound by default unless removed with
1120
+ // ?Sized or ?DynSized . Scan through the predicates and mark any type parameter with
1121
+ // a Sized or DynSized bound, removing the bounds as we find them.
1095
1122
//
1096
1123
// Note that associated types also have a sized bound by default, but we
1097
1124
// don't actually know the set of associated types right here so that's
1098
1125
// handled in cleaning associated types
1099
1126
let mut sized_params = FxHashSet ( ) ;
1127
+ let mut dynsized_params = FxHashSet ( ) ;
1100
1128
where_predicates. retain ( |pred| {
1101
1129
match * pred {
1102
1130
WP :: BoundPredicate { ty : Generic ( ref g) , ref bounds } => {
1103
- if bounds. iter ( ) . any ( |b| b. is_sized_bound ( cx) ) {
1104
- sized_params. insert ( g. clone ( ) ) ;
1105
- false
1106
- } else {
1107
- true
1131
+ let mut retain = true ;
1132
+ for bound in bounds. iter ( ) {
1133
+ if bound. is_sized_bound ( cx) {
1134
+ sized_params. insert ( g. clone ( ) ) ;
1135
+ retain = false ;
1136
+ } else if bound. is_dynsized_bound ( cx) {
1137
+ dynsized_params. insert ( g. clone ( ) ) ;
1138
+ retain = false ;
1139
+ }
1108
1140
}
1141
+ retain
1109
1142
}
1110
1143
_ => true ,
1111
1144
}
1112
1145
} ) ;
1113
1146
1114
- // Run through the type parameters again and insert a ?Sized
1147
+ // Run through the type parameters again and insert a ?Sized or ?DynSized
1115
1148
// unbound for any we didn't find to be Sized.
1116
1149
for tp in & stripped_typarams {
1117
1150
if !sized_params. contains ( & tp. name ) {
1118
1151
where_predicates. push ( WP :: BoundPredicate {
1119
1152
ty : Type :: Generic ( tp. name . clone ( ) ) ,
1120
1153
bounds : vec ! [ TyParamBound :: maybe_sized( cx) ] ,
1121
1154
} )
1155
+ } else if !dynsized_params. contains ( & tp. name ) {
1156
+ where_predicates. push ( WP :: BoundPredicate {
1157
+ ty : Type :: Generic ( tp. name . clone ( ) ) ,
1158
+ bounds : vec ! [ TyParamBound :: maybe_dynsized( cx) ] ,
1159
+ } )
1122
1160
}
1123
1161
}
1124
1162
@@ -1532,14 +1570,37 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
1532
1570
vec ! [ ]
1533
1571
} ;
1534
1572
1535
- // Our Sized/?Sized bound didn't get handled when creating the generics
1573
+ // Our Sized/?Sized/?DynSized bound didn't get handled when creating the generics
1536
1574
// because we didn't actually get our whole set of bounds until just now
1537
- // (some of them may have come from the trait). If we do have a sized
1538
- // bound, we remove it, and if we don't then we add the `?Sized` bound
1539
- // at the end.
1540
- match bounds. iter ( ) . position ( |b| b. is_sized_bound ( cx) ) {
1541
- Some ( i) => { bounds. remove ( i) ; }
1542
- None => bounds. push ( TyParamBound :: maybe_sized ( cx) ) ,
1575
+ // (some of them may have come from the trait).
1576
+ //
1577
+ // We remove `Sized` and `DynSized` bounds, and then possibly add `?Sized`
1578
+ // or `?DynSized`.
1579
+ //
1580
+ // It's theoretically possible to have a `Sized` bound without a `DynSized` bound.
1581
+ // It means the same as having both, since `DynSized` is a supertrait of `Sized`
1582
+ let mut has_sized_bound = false ;
1583
+ let mut has_dynsized_bound = false ;
1584
+ bounds. retain ( |bound| {
1585
+ if bound. is_sized_bound ( cx) {
1586
+ has_sized_bound = true ;
1587
+ false
1588
+ } else if bound. is_dynsized_bound ( cx) {
1589
+ has_dynsized_bound = true ;
1590
+ false
1591
+ } else {
1592
+ true
1593
+ }
1594
+ } ) ;
1595
+ if has_sized_bound {
1596
+ // T
1597
+ // don't push anything
1598
+ } else if has_dynsized_bound {
1599
+ // T: ?Sized
1600
+ bounds. push ( TyParamBound :: maybe_sized ( cx) ) ;
1601
+ } else {
1602
+ // T: ?DynSized
1603
+ bounds. push ( TyParamBound :: maybe_dynsized ( cx) ) ;
1543
1604
}
1544
1605
1545
1606
let ty = if self . defaultness . has_value ( ) {
0 commit comments