@@ -835,7 +835,6 @@ fn clean_ty_generics<'tcx>(
835
835
. into_iter ( )
836
836
. flatten ( )
837
837
. cloned ( )
838
- . filter ( |b| !b. is_sized_bound ( cx) ) ,
839
838
) ;
840
839
841
840
if let Some ( proj) = projection
@@ -862,8 +861,27 @@ fn clean_ty_generics<'tcx>(
862
861
. collect :: < Vec < _ > > ( ) ;
863
862
864
863
for ( param, mut bounds) in impl_trait {
864
+ let mut has_sized = false ;
865
+ bounds. retain ( |b| {
866
+ if b. is_sized_bound ( cx) {
867
+ has_sized = true ;
868
+ false
869
+ } else {
870
+ true
871
+ }
872
+ } ) ;
873
+ if !has_sized {
874
+ bounds. push ( GenericBound :: maybe_sized ( cx) ) ;
875
+ }
876
+
865
877
// Move trait bounds to the front.
866
- bounds. sort_by_key ( |b| !matches ! ( b, GenericBound :: TraitBound ( ..) ) ) ;
878
+ bounds. sort_by_key ( |b| !b. is_trait_bound ( ) ) ;
879
+
880
+ // Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`).
881
+ // Since all potential trait bounds are at the front we can just check the first bound.
882
+ if bounds. first ( ) . map_or ( true , |b| !b. is_trait_bound ( ) ) {
883
+ bounds. insert ( 0 , GenericBound :: sized ( cx) ) ;
884
+ }
867
885
868
886
let crate :: core:: ImplTraitParam :: ParamIndex ( idx) = param else { unreachable ! ( ) } ;
869
887
if let Some ( proj) = impl_trait_proj. remove ( & idx) {
@@ -2107,7 +2125,6 @@ fn clean_middle_opaque_bounds<'tcx>(
2107
2125
cx : & mut DocContext < ' tcx > ,
2108
2126
bounds : Vec < ty:: Clause < ' tcx > > ,
2109
2127
) -> Type {
2110
- let mut regions = vec ! [ ] ;
2111
2128
let mut has_sized = false ;
2112
2129
let mut bounds = bounds
2113
2130
. iter ( )
@@ -2116,10 +2133,7 @@ fn clean_middle_opaque_bounds<'tcx>(
2116
2133
let trait_ref = match bound_predicate. skip_binder ( ) {
2117
2134
ty:: ClauseKind :: Trait ( tr) => bound_predicate. rebind ( tr. trait_ref ) ,
2118
2135
ty:: ClauseKind :: TypeOutlives ( ty:: OutlivesPredicate ( _ty, reg) ) => {
2119
- if let Some ( r) = clean_middle_region ( reg) {
2120
- regions. push ( GenericBound :: Outlives ( r) ) ;
2121
- }
2122
- return None ;
2136
+ return clean_middle_region ( reg) . map ( GenericBound :: Outlives ) ;
2123
2137
}
2124
2138
_ => return None ,
2125
2139
} ;
@@ -2155,10 +2169,20 @@ fn clean_middle_opaque_bounds<'tcx>(
2155
2169
Some ( clean_poly_trait_ref_with_bindings ( cx, trait_ref, bindings) )
2156
2170
} )
2157
2171
. collect :: < Vec < _ > > ( ) ;
2158
- bounds . extend ( regions ) ;
2159
- if !has_sized && !bounds . is_empty ( ) {
2160
- bounds. insert ( 0 , GenericBound :: maybe_sized ( cx) ) ;
2172
+
2173
+ if !has_sized {
2174
+ bounds. push ( GenericBound :: maybe_sized ( cx) ) ;
2161
2175
}
2176
+
2177
+ // Move trait bounds to the front.
2178
+ bounds. sort_by_key ( |b| !b. is_trait_bound ( ) ) ;
2179
+
2180
+ // Add back a `Sized` bound if there are no *trait* bounds remaining (incl. `?Sized`).
2181
+ // Since all potential trait bounds are at the front we can just check the first bound.
2182
+ if bounds. first ( ) . map_or ( true , |b| !b. is_trait_bound ( ) ) {
2183
+ bounds. insert ( 0 , GenericBound :: sized ( cx) ) ;
2184
+ }
2185
+
2162
2186
ImplTrait ( bounds)
2163
2187
}
2164
2188
0 commit comments