@@ -835,7 +835,6 @@ fn clean_ty_generics<'tcx>(
835835 . into_iter ( )
836836 . flatten ( )
837837 . cloned ( )
838- . filter ( |b| !b. is_sized_bound ( cx) ) ,
839838 ) ;
840839
841840 if let Some ( proj) = projection
@@ -862,8 +861,27 @@ fn clean_ty_generics<'tcx>(
862861 . collect :: < Vec < _ > > ( ) ;
863862
864863 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+
865877 // 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+ }
867885
868886 let crate :: core:: ImplTraitParam :: ParamIndex ( idx) = param else { unreachable ! ( ) } ;
869887 if let Some ( proj) = impl_trait_proj. remove ( & idx) {
@@ -2107,7 +2125,6 @@ fn clean_middle_opaque_bounds<'tcx>(
21072125 cx : & mut DocContext < ' tcx > ,
21082126 bounds : Vec < ty:: Clause < ' tcx > > ,
21092127) -> Type {
2110- let mut regions = vec ! [ ] ;
21112128 let mut has_sized = false ;
21122129 let mut bounds = bounds
21132130 . iter ( )
@@ -2116,10 +2133,7 @@ fn clean_middle_opaque_bounds<'tcx>(
21162133 let trait_ref = match bound_predicate. skip_binder ( ) {
21172134 ty:: ClauseKind :: Trait ( tr) => bound_predicate. rebind ( tr. trait_ref ) ,
21182135 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 ) ;
21232137 }
21242138 _ => return None ,
21252139 } ;
@@ -2155,10 +2169,20 @@ fn clean_middle_opaque_bounds<'tcx>(
21552169 Some ( clean_poly_trait_ref_with_bindings ( cx, trait_ref, bindings) )
21562170 } )
21572171 . 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) ) ;
21612175 }
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+
21622186 ImplTrait ( bounds)
21632187}
21642188
0 commit comments